Ejemplo n.º 1
0
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;
	}
}
Ejemplo n.º 2
0
/*  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;
}