hmm... come to think of it, you don't really need a  outter do {} while(0); do you? All your cases are mutual exclusive . so you just do 

bool  done = false

DO_HASH_IF(xxx, xxx);
DO_HASH_IF(xxx, xxx); 

if(!done) {
  error (xxx);
} else {
  push_malloc_string();
}

would this be sufficient ?