#include "filter-ast.h"
#include "filter-parser.h"
-__attribute__((visibility("hidden")))
+#include <common/macros.h>
+
+#define WIDTH_u64_SCANF_IS_A_BROKEN_API "20"
+#define WIDTH_o64_SCANF_IS_A_BROKEN_API "22"
+#define WIDTH_x64_SCANF_IS_A_BROKEN_API "17"
+#define WIDTH_lg_SCANF_IS_A_BROKEN_API "4096" /* Hugely optimistic approximation */
+
+LTTNG_HIDDEN
int yydebug;
-__attribute__((visibility("hidden")))
+LTTNG_HIDDEN
int filter_parser_debug = 0;
-__attribute__((visibility("hidden")))
-int yyparse(struct filter_parser_ctx *parser_ctx);
-__attribute__((visibility("hidden")))
-int yylex(union YYSTYPE *yyval, struct filter_parser_ctx *parser_ctx);
-__attribute__((visibility("hidden")))
+LTTNG_HIDDEN
+int yyparse(struct filter_parser_ctx *parser_ctx, yyscan_t scanner);
+LTTNG_HIDDEN
+int yylex(union YYSTYPE *yyval, yyscan_t scanner);
+LTTNG_HIDDEN
int yylex_init_extra(struct filter_parser_ctx *parser_ctx, yyscan_t * ptr_yy_globals);
-__attribute__((visibility("hidden")))
+LTTNG_HIDDEN
int yylex_destroy(yyscan_t yyparser_ctx);
-__attribute__((visibility("hidden")))
+LTTNG_HIDDEN
void yyrestart(FILE * in_str, yyscan_t parser_ctx);
struct gc_string {
[ NODE_UNARY_OP ] = "NODE_UNARY_OP",
};
-__attribute__((visibility("hidden")))
+LTTNG_HIDDEN
const char *node_type(struct filter_node *node)
{
if (node->type < NR_NODE_TYPES)
* gsrc will be garbage collected immediately, and gstr might be.
* Should only be used to append characters to a string literal or constant.
*/
-__attribute__((visibility("hidden")))
+LTTNG_HIDDEN
struct gc_string *gc_string_append(struct filter_parser_ctx *parser_ctx,
struct gc_string *gstr,
struct gc_string *gsrc)
return gstr;
}
-__attribute__((visibility("hidden")))
+LTTNG_HIDDEN
void setstring(struct filter_parser_ctx *parser_ctx, YYSTYPE *lvalp, const char *src)
{
lvalp->gs = gc_string_alloc(parser_ctx, strlen(src) + 1);
return node;
}
-__attribute__((visibility("hidden")))
-void yyerror(struct filter_parser_ctx *parser_ctx, const char *str)
+LTTNG_HIDDEN
+void yyerror(struct filter_parser_ctx *parser_ctx, yyscan_t scanner, const char *str)
{
fprintf(stderr, "error %s\n", str);
}
-__attribute__((visibility("hidden")))
+LTTNG_HIDDEN
int yywrap(void)
{
return 1;
#define parse_error(parser_ctx, str) \
do { \
- yyerror(parser_ctx, YY_("parse error: " str "\n")); \
+ yyerror(parser_ctx, parser_ctx->scanner, YY_("parse error: " str "\n")); \
YYERROR; \
} while (0)
cds_list_for_each_entry_safe(node, tmp, &ast->allocated_nodes, gc)
free(node);
+ free(ast);
}
-__attribute__((visibility("hidden")))
+LTTNG_HIDDEN
int filter_parser_ctx_append_ast(struct filter_parser_ctx *parser_ctx)
{
- return yyparse(parser_ctx);
+ return yyparse(parser_ctx, parser_ctx->scanner);
}
-__attribute__((visibility("hidden")))
+LTTNG_HIDDEN
struct filter_parser_ctx *filter_parser_ctx_alloc(FILE *input)
{
struct filter_parser_ctx *parser_ctx;
return NULL;
}
-__attribute__((visibility("hidden")))
+LTTNG_HIDDEN
void filter_parser_ctx_free(struct filter_parser_ctx *parser_ctx)
{
int ret;
%define api.pure
/* %locations */
%parse-param {struct filter_parser_ctx *parser_ctx}
-%lex-param {struct filter_parser_ctx *parser_ctx}
+%parse-param {yyscan_t scanner}
+%lex-param {yyscan_t scanner}
%start translation_unit
%token CHARACTER_CONSTANT_START SQUOTE STRING_LITERAL_START DQUOTE
%token ESCSEQ CHAR_STRING_TOKEN
%token ASSIGN COLON SEMICOLON DOTDOTDOT DOT EQUAL COMMA
%token XOR_BIN AND_BIN OR_BIN NOT_BIN
-%token <gs> IDENTIFIER
+%token <gs> IDENTIFIER GLOBAL_IDENTIFIER
%token ERROR
%union
{
$$->u.expression.type = AST_EXP_IDENTIFIER;
$$->u.expression.u.identifier = yylval.gs->s;
}
+ | GLOBAL_IDENTIFIER
+ {
+ $$ = make_node(parser_ctx, NODE_EXPRESSION);
+ $$->u.expression.type = AST_EXP_GLOBAL_IDENTIFIER;
+ $$->u.expression.u.identifier = yylval.gs->s;
+ }
+
| DECIMAL_CONSTANT
{
$$ = make_node(parser_ctx, NODE_EXPRESSION);
$$->u.expression.type = AST_EXP_CONSTANT;
- sscanf(yylval.gs->s, "%" PRIu64,
- &$$->u.expression.u.constant);
+ if (sscanf(yylval.gs->s, "%" WIDTH_u64_SCANF_IS_A_BROKEN_API SCNu64,
+ &$$->u.expression.u.constant) != 1) {
+ parse_error(parser_ctx, "cannot scanf decimal constant");
+ }
}
| OCTAL_CONSTANT
{
$$ = make_node(parser_ctx, NODE_EXPRESSION);
$$->u.expression.type = AST_EXP_CONSTANT;
- sscanf(yylval.gs->s, "0%" PRIo64,
- &$$->u.expression.u.constant);
+ if (!strcmp(yylval.gs->s, "0")) {
+ $$->u.expression.u.constant = 0;
+ } else if (sscanf(yylval.gs->s, "0%" WIDTH_o64_SCANF_IS_A_BROKEN_API SCNo64,
+ &$$->u.expression.u.constant) != 1) {
+ parse_error(parser_ctx, "cannot scanf octal constant");
+ }
}
| HEXADECIMAL_CONSTANT
{
$$ = make_node(parser_ctx, NODE_EXPRESSION);
$$->u.expression.type = AST_EXP_CONSTANT;
- sscanf(yylval.gs->s, "0x%" PRIx64,
- &$$->u.expression.u.constant);
+ if (sscanf(yylval.gs->s, "0x%" WIDTH_x64_SCANF_IS_A_BROKEN_API SCNx64,
+ &$$->u.expression.u.constant) != 1) {
+ parse_error(parser_ctx, "cannot scanf hexadecimal constant");
+ }
}
| FLOAT_CONSTANT
{
$$ = make_node(parser_ctx, NODE_EXPRESSION);
$$->u.expression.type = AST_EXP_FLOAT_CONSTANT;
- sscanf(yylval.gs->s, "%lg",
- &$$->u.expression.u.float_constant);
+ if (sscanf(yylval.gs->s, "%" WIDTH_lg_SCANF_IS_A_BROKEN_API "lg",
+ &$$->u.expression.u.float_constant) != 1) {
+ parse_error(parser_ctx, "cannot scanf float constant");
+ }
}
| STRING_LITERAL_START DQUOTE
{