Пример #1
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;
}
Пример #2
0
/* parser_get_token */
int parser_get_token(Parser * parser, Token ** token)
{
	int ret = 0; /* XXX not sure */
	size_t i;
	ParserCallbackData * pcd;

	if((*token = token_new(parser->filename, parser->line, parser->col))
			== NULL)
		return 1;
	if(parser->last == EOF)
		parser_scan_filter(parser);
#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s() %c\n", __func__, parser->last);
#endif
	for(i = 0; i < parser->callbacks_cnt; i++)
	{
		pcd = &parser->callbacks[i];
		if((ret = pcd->callback(parser, *token, parser->last,
						pcd->data)) <= 0)
			break;
	}
	if(ret == 0 && i != parser->callbacks_cnt)
		return 0; /* there is a token and no error */
	token_delete(*token);
	*token = NULL;
	return (ret >= 0 && parser->last == EOF) ? 0 : 1;
}
Пример #3
0
/* cpp_callback_operator */
static int _cpp_callback_operator(Parser * parser, Token * token, int c,
		void * data)
	/* FIXME probably fails for ".." and similar cases */
{
	CppParser * cp = data;
	size_t i;
	const size_t j = sizeof(_cpp_operators) / sizeof(*_cpp_operators);
	size_t pos;

	for(i = 0; i < _cpp_operators_cnt; i++)
		if(_cpp_operators[i].string[0] == c)
			break;
	if(i == _cpp_operators_cnt) /* nothing found */
		return 1;
	DEBUG_CALLBACK();
	for(pos = 0; i < j;)
	{
		if(_cpp_operators[i].string[pos] == '\0')
			break;
		if(c == _cpp_operators[i].string[pos])
		{
			c = parser_scan_filter(parser);
			pos++;
		}
		else
			i++;
	}
	if(i == j) /* should not happen */
		return -1;
	return _cpp_token_set(cp, token, _cpp_operators[i].code,
			_cpp_operators[i].string);
}
Пример #4
0
/* cpp_callback_otherspace */
static int _cpp_callback_otherspace(Parser * parser, Token * token, int c,
		void * data)
{
	CppParser * cp = data;
	char * str = NULL;
	size_t len = 0;
	char * p;

	assert(c != '\n');
	if(!isspace(c))
		return 1;
	DEBUG_CALLBACK();
	do
	{
		if((p = realloc(str, len + 2)) == NULL)
		{
			free(str);
			return -1;
		}
		str = p;
		str[len++] = c;
	}
	while(isspace((c = parser_scan_filter(parser))) && c != '\n');
	if(str != NULL)
	{
		str[len] = '\0';
		_cpp_token_set(cp, token, CPP_CODE_WHITESPACE, str);
		free(str);
	}
	else
		_cpp_token_set(cp, token, CPP_CODE_WHITESPACE, " ");
	return 0;
}
Пример #5
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;
}
Пример #6
0
/* cpp_callback_comment */
static int _cpp_callback_comment(Parser * parser, Token * token, int c,
		void * data)
{
	CppParser * cp = data;
	char * str = NULL;
	size_t len = 2;
	char * p;

	if(c != '/')
		return 1;
	DEBUG_CALLBACK();
	if((c = parser_scan_filter(parser)) != '*')
		return _cpp_token_set(cp, token, CPP_CODE_OPERATOR_DIVIDE, "/");
	for(c = parser_scan_filter(parser); c != EOF;)
	{
		if(!(cp->filters & CPP_FILTER_COMMENT))
		{
			if((p = realloc(str, len + 3)) == NULL)
				return -error_set_code(1, "%s", strerror(
							errno));
			str = p;
			str[len++] = c;
		}
		if(c == '*')
		{
			if((c = parser_scan_filter(parser)) == '/')
				break;
		}
		else
			c = parser_scan_filter(parser);
	}
	if(c == EOF)
		return -error_set_code(1, "%s", "End of file within a comment");
	parser_scan_filter(parser);
	if(str == NULL)
		return _cpp_token_set(cp, token, CPP_CODE_WHITESPACE, " ");
	str[0] = '/';
	str[1] = '*';
	str[len++] = '/';
	str[len] = '\0';
	_cpp_token_set(cp, token, CPP_CODE_COMMENT, str); /* XXX may fail */
	free(str);
	return 0;
}
Пример #7
0
/* cpp_callback_comma */
static int _cpp_callback_comma(Parser * parser, Token * token, int c,
		void * data)
{
	CppParser * cp = data;

	if(c != ',')
		return 1;
	DEBUG_CALLBACK();
	parser_scan_filter(parser);
	return _cpp_token_set(cp, token, CPP_CODE_COMMA, ",");
}
Пример #8
0
/* cpp_callback_unknown */
static int _cpp_callback_unknown(Parser * parser, Token * token, int c,
		void * data)
{
	CppParser * cp = data;
	char buf[2] = "\0";

	if(c == EOF)
		return 1;
	DEBUG_CALLBACK();
	buf[0] = c;
	parser_scan_filter(parser);
	return _cpp_token_set(cp, token, CPP_CODE_UNKNOWN, buf);
}
Пример #9
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;
}
Пример #10
0
/* cpp_callback_inject */
static int _cpp_callback_inject(Parser * parser, Token * token, int c,
		void * data)
{
	CppParser * cp = data;
	char buf[2] = "\0";

	if(cp->inject_first == 0)
		return 1;
	DEBUG_CALLBACK();
	if(c == EOF)
		return 1;
	/* the current character actually goes after the substitution */
	buf[0] = c;
	if(string_append(&cp->inject, buf) != 0)
		return -1;
	parser_scan_filter(parser);
	return 1;
}
Пример #11
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;
}
Пример #12
0
/* cpp_parse_word */
static char * _cpp_parse_word(Parser * parser, int c)
{
	char * str = NULL;
	size_t len = 0;
	char * p;

	do
	{
		if((p = realloc(str, len + 2)) == NULL)
		{
			error_set_code(1, "%s", strerror(errno));
			free(str);
			return NULL;
		}
		str = p;
		str[len++] = c;
	}
	while(_cpp_isword((c = parser_scan_filter(parser))));
	str[len] = '\0';
	return str;
}
Пример #13
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;
}