void Parser::IncludedFile::save_conditional(Cond *c, int rh) { CC_STRING tmp; static const char *directives[] = {NULL, "if", "elif", "else"}; assert(c->type <= Cond::CT_ELSE); if(directives[c->type]) { tmp.Format(" %-4u %s %s ", rh, directives[c->type], (c->value ? "true" : "false")); cr_text += tmp; if(c->boff) tmp.Format("%u,%d ", c->begin, c->boff); else tmp.Format("%u ", c->begin); cr_text += tmp; if(c->eoff) tmp.Format("%u,%d\n", c->end, c->eoff); else tmp.Format("%u\n", c->end); cr_text += tmp; } }
/* Parse the input file and update the global symbol table and macro table, * output the stripped file contents to devices if OUTFILE is not nil. * * Returns a pointer to the error messages on failure, or nil on success. */ bool Parser::DoFile(InternalTables *intab, size_t num_preprocessors, File *infile, ParserContext *ctx) { bool ignored; FILE *out_fp; bool retval = false; CC_STRING bak_fname, out_fname; struct stat stb; struct utimbuf utb; if(ctx) { ignored = ctx->check_ignore(infile->name); if( ignored && ! has_dep_file() ) return true; } else ignored = false; if( stat(infile->name, &stb) == 0 ) { utb.actime = stb.st_atime; utb.modtime = stb.st_mtime; } if( ! infile->Open() ) { errmsg.Format("Cannot open \"%s\" for reading\n"); return false; } out_fp = NULL; if(ctx != NULL && ctx->outfile != ParserContext::OF_NULL ) { if( ctx->outfile == ParserContext::OF_STDOUT ) out_fp = stdout; else { #if SANITY_CHECK assert( ! ctx->baksuffix.isnull() ); #endif if( ctx->baksuffix[0] != ParserContext::MAGIC_CHAR ) bak_fname = infile->name + ctx->baksuffix; else out_fname = infile->name; int fd; char tmp_outfile[32]; strcpy(tmp_outfile, "@cl@-XXXXXX"); fd = mkstemp(tmp_outfile); if( fd < 0 ) { errmsg.Format("Cannot open \"%s\" for writing\n", tmp_outfile); infile->Close(); return false; } out_fp = fdopen(fd, "wb"); out_fname = tmp_outfile; } } if(ctx == NULL) memset(writers, 0, sizeof(writers)); else { writers[VCH_CL] = NULL; if(!ctx->of_array[VCH_DEP].isnull()) writers[VCH_DEP] = gvar_file_writers[VCH_DEP]; if(!ctx->of_array[VCH_CV].isnull()) writers[VCH_CV] = gvar_file_writers[VCH_CV]; } if( num_preprocessors >= COUNT_OF(Parser::preprocessors) ) num_preprocessors = COUNT_OF(Parser::preprocessors); Reset(intab, num_preprocessors, ctx); if(has_dep_file()) AddDependency("", infile->name); PushIncludedFile(infile, out_fp, COUNT_OF(Parser::preprocessors), false, conditionals.size()); if(ctx != NULL) { GetCmdLineIncludeFiles(ctx->imacro_files, 2); GetCmdLineIncludeFiles(ctx->include_files, COUNT_OF(preprocessors)); } if( ! RunEngine(0) ) goto error; SaveDepInfo(deptext); if( conditionals.size() != 0 ) errmsg = "Unmatched #if"; else retval = true; error: if(!retval) { if(included_files.size() > 0) { CC_STRING tmp; tmp.Format("%s:%u: %s\n%s\n", GetCurrentFileName().c_str(), GetCurrentLineNumber(), pline.from.c_str(), GetError()); errmsg = tmp; } #if 0 IncludedFile *ilevel; while(included_files.size() > 0) { ilevel = PopIncludedFile(); if(infile != ilevel->ifile) delete ilevel; } #endif } if(out_fp != NULL && out_fp != stdout) fclose(out_fp); if( retval && ctx != NULL && ! ignored ) { CC_STRING semname; sem_t *sem; semname = MakeSemaName(infile->name); sem = sem_open(semname.c_str(), O_CREAT, 0666, 1); sem_wait(sem); if( ! bak_fname.isnull() ) rename(infile->name, bak_fname); if( ! out_fname.isnull() ) { rename(out_fname, infile->name); utime(infile->name.c_str(), &utb); } sem_post(sem); sem_unlink(semname.c_str()); } else if( ! out_fname.isnull() ) unlink(out_fname.c_str()); return retval; }