Пример #1
0
int fsl_copy(const CC_STRING& src, const CC_STRING& dst)
{
	int fs, fd, last_errno = 0;
	static char buf[512];
	const int chunksize = sizeof(buf);

	fs = open(src.c_str(), O_RDONLY, 0666);
	if(fs < 0) {
		last_errno = errno;
		goto error;
	}
	fd = open(dst.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0666);
	if(fd < 0) {
		last_errno = errno;
		goto error;
	}
	if(fs > 0 && fd > 0) {
		int n1, n2;
		do {
			n1 = read(fs, buf, chunksize);
			n2 = write(fd, buf, n1);
			if(n1 != n2) {
				last_errno = errno;
				break;
			}
		} while(n2 == chunksize);
		close(fs);
		close(fd);
	}
error:
	return - last_errno;
}
Пример #2
0
CC_STRING CMaExpander::TryExpand()
{
	CToken token;
	CC_STRING outs;
	static int debug_level;
	CC_STRING saved_inStr = inStr;

	debug_level++;


	while(1) {
		const char *const last_pos  = pos;

		IgnoreSpaces();
		if( ! get_token(tc, &pos, &token, for_include) )
			break;
		if( token.attr == CToken::TA_IDENT ) {
			CMacro *ma;
			CC_STRING tmp;
			ma = GetMacro(token.id);
			if( IS_MACRO(ma) && ! in_defined_context() ) {
				if( IS_FLM(ma) ) {
					skip_blanks(pos);
					if( *pos == '(' ) {
						tmp = Expand_FLM(ma);
					}
					else
						goto do_cat;
				} else {
					tmp = Expand_OLM(ma);
				}

				const ssize_t offset = last_pos - inStr.c_str();
				CC_STRING newStr;
				
				newStr.strcat(inStr.c_str(), last_pos);
				newStr += tmp;
				newStr += pos;
				
				inStr = newStr;
				pos   = inStr.c_str() + offset;
			} else
				goto do_cat;
		} else {
		do_cat:
			outs.strcat(last_pos, pos);
		}
		last_ids[0] = last_ids[1];
		last_ids[1] = token.id;
	}

//	printf("Leave [%u] %s\n", debug_level, outs.c_str());
	--debug_level;
//	fprintf(stderr, "*** %u: %s => %s\n", debug_level, saved_inStr.c_str(), outs.c_str());

	return outs;
}
Пример #3
0
void CMaExpander::Trim(CC_STRING& s)
{
	const char *p1, *p2, *end = s.c_str() + s.size();

	for(p1 = s.c_str() ; p1 != '\0' && isblank(*p1); p1++ ) ;
	for(p2 = end - 1 ; p2 >= s.c_str() && isblank(*p2); p2-- ) ;
	p2++;
	if(p2 < end && isblank(*p2) )
		p2++;
	CC_STRING ns;
	while(p1 < p2)
		ns += *p1++;
	s = ns;
}
Пример #4
0
int fsl_copy_with_parent(const CC_STRING& src, const CC_STRING& dst)
{
	CC_STRING ddir;
	const char *pos;
	int retval;

	pos = strrchr(dst.c_str(), '/');
	if(pos != NULL) {
		ddir.strcat(dst.c_str(), pos);
		retval = fsl_mkdir(ddir);
		if( retval != 0)
			return retval;
	}
	return fsl_copy(src, dst);
}
Пример #5
0
bool Parser::GetCmdLineIncludeFiles(const CC_ARRAY<CC_STRING>& ifiles, size_t np)
{
	if( ifiles.size() == 0)
		return true;

	CC_STRING path;
	bool in_compiler_dir;
	for(size_t i = 0; i < ifiles.size(); i++) {
		if(!rtc->get_include_file_path(ifiles[i], CC_STRING(""), true, false, path, &in_compiler_dir)) {
			errmsg.Format("Can not find include file \"%s\"", ifiles[i].c_str());
			return false;
		}
		RealFile *file;
		file = new RealFile;
		file->SetFileName(path);

		if( ! file->Open() ) {
			errmsg.Format("Can not open include file \"%s\"", ifiles[i].c_str());
			return false;
		}
		PushIncludedFile(file, NULL, np, in_compiler_dir, conditionals.size());
		if( ! RunEngine(1) )
			return false;

		if(has_dep_file() && ! in_compiler_dir)
			AddDependency("  ",  path.c_str());
	}
	return true;
}
Пример #6
0
void fsl_mp_append(const CC_STRING& filename, const void *buf, size_t n)
{
	int fd;
	fd = open(filename.c_str(), O_CREAT|O_BINARY|O_WRONLY|O_APPEND, 0664);
	fsl_mp_fdappend(fd, buf, n);
	close(fd);
}
Пример #7
0
//
// Get the include file name without surrouding angle brackets or double quoation marks
//
static CC_STRING GetIncludeFileName(const CC_STRING& line, bool& quoted)
{
	const char *p1, *p2;
	CC_STRING filename;
	char style = '\0';

	p1 = line.c_str();
	skip_blanks(p1);

	if( *p1 == '"')
		style = '"';
	else if( *p1 == '<' )
		style = '>';
	else
		goto error;
	p1++;
	skip_blanks(p1);
	p2 = p1 + strlen(p1) - 1;
	while( *p2 == '\t' || *p2 == ' ' || *p2 == '\r' || *p2 == '\n') {
		if(--p2 < p1)
			goto error;
	}
	if( *p2 != style )
		goto error;
	p2--;
	while( *p2 == '\t' || *p2 == ' ' ) {
		if(--p2 < p1)
			goto error;
	}
	filename = CC_STRING(p1, p2+1);
	quoted = (style == '"');

error:
	return filename;
}
Пример #8
0
int fsl_mkdir(const CC_STRING& dirname)
{
    CC_STRING newdir;
	char *p, *dir;
	struct stat stb;
	int retval = 0;

	if( dirname[0] != '/' ) {
        newdir = fsl_realpath(dirname);
		if( newdir.isnull() ) {
			retval = -EINVAL;
			goto fail;
		}
	} else
		newdir = dirname.c_str();

	dir = (char*)newdir.c_str();
	if(newdir[0] == '/')
		p = (char*)newdir.c_str() + 1;
	else
		p = (char*)newdir.c_str();
	while(1) {
		char c = *p;
		if(c == 0 || c == '/') {
			const char saved_char = *p;
			*p = '\0';
			if(stat(dir, &stb) != 0) {
				if ( mkdir(dir, 0775) != 0 ) {
					retval = -errno;
					goto fail;
				}
			} else if( ! S_ISDIR(stb.st_mode) ) {
				retval = -EEXIST;
				goto fail;
			}
			if(c == '\0')
				break;
			*p = saved_char;
		}
		p ++;
	}

fail:
	return retval;
}
Пример #9
0
void Parser::SaveDepInfo(const CC_STRING& s)
{
	if(writers[VCH_DEP] && !s.isnull()) {
		ssize_t ret;
		ret = writers[VCH_DEP]->Write(s.c_str(), s.size());
		if(ret < 0)
			exit(-EPIPE);
	}
}
Пример #10
0
void fsl_mp_write(const CC_STRING& filename, const void *buf, size_t n)
{
	int fd;

	fd = open(filename.c_str(), O_CREAT|O_BINARY|O_WRONLY|O_TRUNC, 0664);
	flock(fd, LOCK_EX);
	(void) write(fd, buf, n);
	flock(fd, LOCK_UN);
	close(fd);
}
Пример #11
0
CC_STRING fsl_dirname(const CC_STRING& path)
{
	char *tmp;
	CC_STRING dir;

	tmp = strdup(path.c_str());
	dir = dirname(tmp);
	free(tmp);
	return dir;
}
Пример #12
0
bool CMaExpander::IsValidToken(const CC_STRING& s)
{
	const char *p = s.c_str();
	if(p == NULL)
		return false;
	if( ! isalpha(*p) && *p != '_' )
		return false;
	for(p++; *p != '\0'; p++ ) {
		if( isblank(*p) )
			break;
		if( ! is_id_char(*p) )
			return false;
	}
	return true;
}
Пример #13
0
static CC_STRING MakeSemaName(const CC_STRING& filename)
{
	CC_STRING sname;
	const char *p;
	char c;

	for(p = filename.c_str(); (c = *p) != 0; p++) {
		if(c == '/' || c == '\\')
			sname += '-';
		else if(c == '.')
			c += '@';
		else
			sname += c;
	}
	return sname;
}
Пример #14
0
static void __NO_USE__ dump(const XCHAR *xc)
{
	CC_STRING s;
	char buf[32];
	while( *xc != 0) {
		if( IS_MA_PAR0(*xc) )
			snprintf(buf, sizeof(buf), "\\%u", (uint8_t)*xc );
		else if( IS_MA_PAR1(*xc) )
			snprintf(buf, sizeof(buf), "#\\%u", (uint8_t)*xc );
		else if( IS_MA_PAR2(*xc) )
			snprintf(buf, sizeof(buf), "##\\%u", (uint8_t)*xc );
		else
			snprintf(buf, sizeof(buf), "%c", *xc);
		s += buf;
		xc++;
	}
	if( ! s.empty() )
		printf("%s\n", s.c_str());
}
Пример #15
0
CC_STRING fsl_realpath(const CC_STRING& src)
{
    char dest[4096];
	const char *s;
	char *d;
	int state = 0;
	
	if( src[0] != '/' ) {
		(void) getcwd(dest, sizeof(dest));
		d = dest + strlen(dest);
		*d ++ = '/';
	} else
		d = dest;
	s = src.c_str();
	while(1) {
		const char c = *s++;
		switch(state) {
		case 0:
			switch(c) {
			case '\0':    *d = c; state = 1; break;
			case UNIX_DD:
			case DOS_DD:  *d++ = c; state = 3; break;
			case '.':     *d++ = c; state = 4; break;
			default:      *d++ = c; break;
			}
			break;
		case 1:	
			#if !HAVE_TRAILING_SPLASH
				if( *(d-1) == UNIX_DD )
					*--d   = '\0';
			#else
				if( *(d-1) != UNIX_DD )
					*d++ = UNIX_DD, *d = '\0';
			#endif
			goto done;
		case 2:	goto fail;
		case 3:	
			switch(c) {
			case '\0':    *d = c; state = 1; break;
			case UNIX_DD:
			case DOS_DD:  break;
			case '.':     *d++ = c; state = 4; break;
			default:      *d++ = c; state = 0; break;
			}
			break;
		case 4:
			switch(c) {
			case '\0':    *d = c; state = 1; break;
			case UNIX_DD:
			case DOS_DD:  state = 3; d -= 1; break;
			case '.':     *d++ = c; state = 5; break;
			default:      *d++ = c; state = 0; break;
			}
			break;
		case 5:
			switch(c) {
			case '\0':    state = 1; goto uplevel;
			case UNIX_DD:
			case DOS_DD:  state = 3; 
				{
					char *t;
				uplevel:
					t = __stdpath_uplevel(dest, d);
					if(t == NULL)
						goto fail;
					d = t;
					if(c == '\0') *d = '\0';
					break;
				}
			default:      state = 2; break;
			}
			break;
		}
	}
done:
	return dest;
fail:
	return NULL;
}
Пример #16
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;
}
Пример #17
0
CC_STRING CMaExpander::Expand_FLM(CMacro *ma)
{
	CC_STRING outs;
	CC_ARRAY<CC_STRING> margs;
	CC_STRING carg;
	const char *p = pos;
	int level;

	skip_blanks(p);
	if( iseol(*p) ) {
		gex.format("Macro \"%s\" expects arguments", TR(tc,ma->id));
		throw &gex;
	}
	if( *p != '(' ) {
		gex = "Macro expects '('";
		throw &gex;
	}

	p++;
	skip_blanks(p);
	level = 1;
	while( 1 ) {
		if( iseol(*p) )
			break;

		if( *p == ','  ) {
			if( level == 1 && ( ! ma->va_args || (margs.size() + 1 < ma->nr_args) ) ) {
				Trim(carg);
				margs.push_back(carg);
				carg.clear();
			} else {
				carg += ',';
				skip_blanks(p);
			}
		} else if(*p == '(') {
			level ++;
			carg += '(';
		} else if(*p == ')') {
			level --;
			if(level == 0) {
				p++;
				Trim(carg);
				margs.push_back(carg);
				carg.clear();
				break;
			} else
				carg += ')';
		} else {
			carg += *p;
		}
		p++;
	}
	pos = p;

	XCHAR *xc;
	CC_STRING s;
	size_t n;

	n = ma->nr_args;
	assert(n != CMacro::OL_M);
	if(n != margs.size()) {
		if( ma->va_args && margs.size() + 1 == n ) {
			margs.push_back(CC_STRING(""));
		} else {
			gex.format("Macro \"%s\" requires %u arguments, but %u given",
				TR(tc,ma->id), n, margs.size() );
			throw &gex;
		}
	}

	for(xc = ma->parsed; *xc != 0; xc++) {
		if(IS_MA_PAR2(*xc) || IS_MA_PAR0(*xc)) {
			const CC_STRING& carg = margs[(uint8_t)*xc];
			CMaExpander expander2(tc, carg.c_str(), for_include);
			CC_STRING tmp;
			tmp = expander2.TryExpand();
			s += tmp;
		} else if(IS_MA_PAR1(*xc)) {
			const CC_STRING& carg = margs[(uint8_t)*xc];
			s += '"';
			s += carg;
			s += '"';
		} else {
			s += (char) *xc;
		}
	}
	outs += s;

	return outs;
}
Пример #18
0
int Parser::Compute(const char *line)
{
	static const char opp[] = { '<', '=', '>', 'X'};
	enum {
		STAT_INIT,
		STAT_OPR1,
		STAT_OPR2,
		STAT_OPND,
		STAT_DEFINED,  /* defined    */
		STAT_DEFINED1, /* defined(   */
		STAT_DEFINED2, /* defined(X  */
	} state;
	CC_STACK<sym_t>  opr_stack;
	CC_STACK<SynToken>  opnd_stack;
	sym_t last_opr = SSID_SHARP;
	SynToken last_token;
	char sign;
	const char *symbol = NULL;
	LOG_VERB dml = LOGV_DEBUG;
	CC_STRING expansion;

	if(!gvar_preprocess_mode) {
		/*
		 *  Keep `#if 0' blocks which are usually user comments.
		 */
		char *copied_line = strdup(line);
		const char *first = strtok(copied_line, " \t");
		int ignore = 0;
		/* Simple code and work properly in most cases */
		if(first && first[0] == '0')
			ignore = 1;
		free(copied_line);
		if(ignore)
			return TSV_X;
	}

	expansion = ExpandLine(intab, false, line, errmsg);
	if( !errmsg.isnull() ) {
		return TSV_X;
	}

	ReadReq req(expansion.c_str());
	SynToken& token = req.token;
	opr_stack.push(SSID_SHARP);
	log(dml, "PUSH OPR: #\n");
	sign = 0;
	state = STAT_OPR1;
	while(1) {
		sym_t  opr;
		const char *last_pos = req.cp;
		int ret;

		ret = ReadToken(intab, &req, false);
		if( ret == 0 )
			break;
		else if( ret < 0 )
			goto error;

		if( token.attr == SynToken::TA_CHAR )
			token.attr = SynToken::TA_INT;
		if( sign != 0 ) {
			if(token.attr != SynToken::TA_UINT && token.id != SSID_DEFINED) {
				errmsg.Format("%s following %c", TR(intab,token.id), sign);
				goto error;
			}
			if(sign == '-') {
				token.attr = SynToken::TA_INT;
				token.i32_val = -token.i32_val;
			}
			sign = 0;
		} else if( (token.id == SSID_ADDITION || token.id == SSID_SUBTRACTION) &&  CheckPrevOperator(last_opr)) {
			sign = token.id == SSID_ADDITION ? '+' : '-';
			goto next;
		}

		switch(state) {
		case STAT_INIT:
			if(IsOperator(token.id))
				state = STAT_OPR1;
			else if(token.id == SSID_DEFINED)
				state = STAT_DEFINED;
			else if(token.attr == SynToken::TA_IDENT)
				state = STAT_OPND;
			break;
		case STAT_OPND:
			if(IsOperator(token.id))
				state = STAT_OPR1;
			else {
				errmsg = "Adjacent operands";
				goto error;
			}
			break;
		case STAT_OPR1:
			if(IsOperator(token.id))
				state = STAT_OPR2;
			else if(token.id == SSID_DEFINED)
				state = STAT_DEFINED;
			else
				state= STAT_INIT;
			break;
		case STAT_OPR2:
			if(IsOperator(token.id)) {
			} else if(token.id == SSID_DEFINED)
				state = STAT_DEFINED;
			else
				state = STAT_INIT;
			break;
		case STAT_DEFINED:
			if(token.id == SSID_LEFT_PARENTHESIS)
				state = STAT_DEFINED1;
			else if(token.attr == SynToken::TA_IDENT) {
				CheckSymbolDefined(last_pos, false, &token);
				if(!errmsg.isnull())
					goto error;
				state = STAT_INIT;
			}
			break;
		case STAT_DEFINED1:
			if(token.attr == SynToken::TA_IDENT) {
				state = STAT_DEFINED2;
				symbol = last_pos;
			} else {
				errmsg = "Syntax error: ";
				goto error;
			}
			break;
		case STAT_DEFINED2:
			if(token.id == SSID_RIGHT_PARENTHESIS) {
				CheckSymbolDefined(symbol, false, &token);
				if(!errmsg.isnull())
					goto error;
				state = STAT_INIT;
				opnd_stack.push(token);
				opr = token.id;
				goto next;
			} else {
				errmsg = "Unmatched (";
				goto error;
			}
			break;
		}
		if(state == STAT_DEFINED || state == STAT_DEFINED1 || state == STAT_DEFINED2)
			goto next;

		if( token.id == SynToken::TA_UINT || token.id == SynToken::TA_INT )
			log(dml, "Current: %u\n", token.u32_val);
		else
			log(dml, "Current: %s\n", TR(intab,token.id));
//		log(dml, "OPR  Stack: \n", opr_stack);
//		log(dml, "OPND Stack: \n", opnd_stack);
		opr = token.id;
		if( IsOperator(opr) ) {
			sym_t opr0;
			int result;
again:
			opr0 = opr_stack.top();
			result = intab->opMat.Compare(opr0, opr);
			log(dml, "Compare: %s %c %s\n", TR(intab,opr0),opp[1+result],TR(intab,opr));
			switch(result) {
			case _EQ:
				opr_stack.pop(opr0);
				break;
			case _GT:
				opr_stack.pop(opr0);
				if( ! CalculateOnStackTop(opr0, opnd_stack, opr_stack) ) {
					goto error;
				}
				goto again;
			case _LT:
				opr_stack.push(opr);
				break;
			case _XX:
				errmsg.Format("Cannot compare \"%s\" and \"%s\"", TR(intab,opr0), TR(intab,opr));
				log(LOGV_ERROR, "*ERROR* %s\n", errmsg.c_str());
				goto error;
			}
		} else {
			opnd_stack.push(token);
		}

	next:
		last_opr = opr;
	}

	do {
		sym_t opr0;
		int result;

		if( ! opr_stack.pop(opr0) )
			goto error;
		result = intab->opMat.Compare(opr0, SSID_SHARP);
		log(dml, "Compare: %s %c #\n", TR(intab,opr0),opp[result]);
		switch(result) {
		case _EQ:
			break;
		case _GT:
			if( ! CalculateOnStackTop(opr0, opnd_stack, opr_stack) ) {
				goto error;
			}
			break;
		default:
			log(LOGV_ERROR, "%s:%u: Bad expression\n", __func__,  __LINE__);
			errmsg = "[1] Bad expression";
			goto error;
		}
	} while( opr_stack.size() != 0 );

	if( opnd_stack.size() != 1 ) {
		log(LOGV_ERROR, "%s:%u: Bad expression\n", __func__,  __LINE__);
		errmsg = "[2] Bad expression";
		goto error;
	}

	if( opnd_stack.top().attr == SynToken::TA_IDENT ) {
		if( gvar_preprocess_mode ) {
			return TSV_0;
		}
		return TSV_X;
	}
	log(dml, "Numberic Value: %u\n", opnd_stack.top().i32_val);;
	return !!opnd_stack.top().i32_val;

error:
	log(LOGV_ERROR, "*Error* %s\n", errmsg.c_str());
	return gvar_preprocess_mode ? TSV_0 : TSV_X;
}