Esempio n. 1
0
/* cpp_token_set */
static int _cpp_token_set(CppParser * cp, Token * token, TokenCode code,
		char const * string)
{
	if(token_set_string(token, string) != 0)
		return -1;
	if(cp->queue_code == CPP_CODE_NULL)
	{
		token_set_code(token, code);
		return 0;
	}
	/* we are parsing a directive */
	token_set_code(token, CPP_CODE_META_DATA);
	if(code == CPP_CODE_COMMENT)
		/* comments within directives are whitespaces */
		string = " ";
	if(cp->queue_string == NULL)
	{
		/* left-trim spaces */
		for(; isspace((unsigned char)string[0]); string++);
		if((cp->queue_string = string_new(string)) == NULL)
			return -1;
	}
	else if(string_append(&cp->queue_string, string) != 0)
		return -1;
	return 0;
}
Esempio n. 2
0
static int _parser_scan(State * state)
{
	int ret;
	TokenCode code;
	char const * string;

	if(state->token != NULL)
		token_delete(state->token);
	if((ret = _scan_skip_meta(state)) != 0
			|| state->token == NULL)
		return ret;
	code = token_get_code(state->token);
	string = token_get_string(state->token);
	if(code == AS_CODE_WORD)
	{
		if(string != NULL && string[0] == '$')
			token_set_code(state->token, AS_CODE_IMMEDIATE);
	}
	else if(code == AS_CODE_OPERATOR_MODULO)
	{
		/* FIXME ugly workaround */
		if((ret = _scan_skip_meta(state)) != 0)
			return ret;
		if(_parser_is_code(state, AS_CODE_WORD))
			token_set_code(state->token, AS_CODE_REGISTER);
	}
	return 0;
}
Esempio n. 3
0
/* cpp_callback_directive */
static int _cpp_callback_directive(Parser * parser, Token * token, int c,
		void * data)
{
	CppParser * cpp = data;
	char * str;
	size_t i;

	if(cpp->directive_control != 1 || cpp->queue_code != CPP_CODE_NULL
			|| !_cpp_isword(c))
		return 1;
	DEBUG_CALLBACK();
	if((str = _cpp_parse_word(parser, c)) == NULL)
		return -1;
	for(i = 0; _cpp_directives[i] != NULL; i++)
		if(strcmp(str, _cpp_directives[i]) == 0)
			break;
	if(_cpp_directives[i] != NULL)
	{
		cpp->queue_code = CPP_CODE_META_FIRST + i;
		cpp->queue_string = NULL;
	}
	else
	{
		cpp->queue_code = CPP_CODE_META_ERROR;
		cpp->queue_string = string_new_append("Invalid directive: #",
				str, ":", NULL); /* XXX check for errors */
	}
	token_set_code(token, CPP_CODE_META_DATA);
	token_set_string(token, str);
	free(str);
	return 0;
}
Esempio n. 4
0
/* cpp_callback_quote */
static int _cpp_callback_quote(Parser * parser, Token * token, int c,
		void * data)
{
	CppParser * cp = data;
	int escape = 0;
	char * str = NULL;
	size_t len = 0;
	char * p;

	if(c == '\'')
		token_set_code(token, CPP_CODE_SQUOTE);
	else if(c == '"')
		token_set_code(token, CPP_CODE_DQUOTE);
	else
		return 1;
	DEBUG_CALLBACK();
	while((p = realloc(str, len + 3)) != NULL)
	{
		str = p;
		str[len++] = c;
		if((c = parser_scan_filter(parser)) == EOF || c == '\n')
			break;
		if(escape)
			escape = 0;
		else if(c == str[0])
			break;
		else if(c == '\\')
			escape = 1;
	}
	if(p == NULL) /* there was an error with realloc() */
	{
		error_set_code(1, "%s", strerror(errno));
		free(str);
		return -1;
	}
	else if(c == str[0]) /* the quoted string is properly closed */
	{
		str[len++] = str[0];
		parser_scan_filter(parser);
	} /* XXX else we should probably issue a warning */
	str[len] = '\0';
	/* XXX keep code earlier, may fail */
	_cpp_token_set(cp, token, token_get_code(token), str);
	free(str);
	return 0;
}
Esempio n. 5
0
/* cpp_callback_header */
static int _cpp_callback_header(Parser * parser, Token * token, int c,
		void * data)
{
	CppParser * cp = data;
	char end;
	char * str = NULL;
	size_t len = 0;
	char * p;

	if(cp->directive_control != 1 || cp->queue_code != CPP_CODE_META_INCLUDE
			|| (c != '<' && c != '"'))
		return 1;
	DEBUG_CALLBACK();
	end = (c == '<') ? '>' : '"';
	while((p = realloc(str, len + 3)) != NULL)
	{
		str = p;
		str[len++] = c;
		if((c = parser_scan_filter(parser)) == EOF || c == '\n')
			break;
		else if(c == end)
			break;
	}
	if(p == NULL) /* there was an error with realloc() */
	{
		error_set_code(1, "%s", strerror(errno));
		free(str);
		return -1;
	}
	else if(c == end) /* the header name is properly closed */
	{
		str[len++] = c;
		parser_scan_filter(parser);
	}
	str[len] = '\0';
	token_set_code(token, CPP_CODE_META_DATA);
	token_set_string(token, str);
	if(cp->queue_string == NULL || strlen(cp->queue_string) == 0)
	{
		free(cp->queue_string);
		cp->queue_string = str;
	}
	else
	{
		free(str);
		cp->queue_code = CPP_CODE_META_ERROR;
		free(cp->queue_string);
		/* XXX may be followed by junk */
		cp->queue_string = strdup("Syntax error");
	}
	return 0;
}
Esempio n. 6
0
/* cpp_callback_newline */
static int _cpp_callback_newline(Parser * parser, Token * token, int c,
		void * data)
{
	CppParser * cpp = data;

	if(c != '\n')
		return 1;
	DEBUG_CALLBACK();
	cpp->directive_newline = 1;
	cpp->queue_ready = 1;
	parser_scan_filter(parser);
	token_set_code(token, CPP_CODE_NEWLINE);
	token_set_string(token, "\n");
	return 0;
}
Esempio n. 7
0
/* cpp_callback_control */
static int _cpp_callback_control(Parser * parser, Token * token, int c,
		void * data)
{
	CppParser * cpp = data;

	if(cpp->directive_newline != 1 || c != '#')
	{
		cpp->directive_newline = 0;
		return 1;
	}
	DEBUG_CALLBACK();
	parser_scan_filter(parser);
	token_set_code(token, CPP_CODE_META_DATA);
	token_set_string(token, "#");
	cpp->directive_newline = 0;
	cpp->directive_control = 1;
	cpp->queue_code = CPP_CODE_NULL;
	return 0;
}
Esempio n. 8
0
/* cpp_callback_dequeue */
static int _cpp_callback_dequeue(Parser * parser, Token * token, int c,
		void * data)
{
	int ret = 0;
	CppParser * cpp = data;

	if(cpp->queue_ready == 0)
		return 1;
	cpp->queue_ready = 0;
	if(cpp->queue_code == CPP_CODE_NULL && cpp->queue_string == NULL)
		return 1;
	DEBUG_CALLBACK();
	token_set_code(token, cpp->queue_code);
	switch(cpp->queue_code)
	{
		case CPP_CODE_META_DEFINE:
		case CPP_CODE_META_ELIF:
		case CPP_CODE_META_IF:
		case CPP_CODE_META_IFDEF:
		case CPP_CODE_META_IFNDEF:
		case CPP_CODE_META_INCLUDE:
		case CPP_CODE_META_UNDEF:
			token_set_string(token, "");
			token_set_data(token, cpp->queue_string);
			cpp->queue_string = NULL;
			break;
		case CPP_CODE_META_ERROR:
		case CPP_CODE_META_WARNING:
			token_set_string(token, (cpp->queue_string != NULL)
					? cpp->queue_string : "");
			break;
		default:
			token_set_string(token, "");
			break;
	}
	cpp->queue_code = CPP_CODE_NULL;
	string_delete(cpp->queue_string);
	cpp->queue_string = NULL;
	cpp->directive_newline = 1;
	cpp->directive_control = 0;
	return ret;
}
Esempio n. 9
0
/* cpp_callback_whitespace */
static int _cpp_callback_whitespace(Parser * parser, Token * token, int c,
		void * data)
{
	CppParser * cpp = data;
	char * str = NULL;
	size_t len = 0;
	char * p;

	if(!isspace(c))
		return 1;
	DEBUG_CALLBACK();
	do
	{
		if(c != '\n')
			continue;
		if((p = realloc(str, len + 2)) == NULL)
		{
			free(str);
			return -1;
		}
		str = p;
		str[len++] = c;
	}
	while(isspace((c = parser_scan_filter(parser))));
	token_set_code(token, CPP_CODE_WHITESPACE);
	if(str != NULL) /* some newlines were encountered */
	{
		str[len] = '\0';
		token_set_string(token, str);
		free(str);
		cpp->directive_newline = 1;
		cpp->queue_ready = 1;
		return 0;
	}
	token_set_string(token, " ");
	if(cpp->queue_code != CPP_CODE_NULL && cpp->queue_string != NULL)
		string_append(&cpp->queue_string, " ");
	return 0;
}