diff mbox series

[07/17] libtracefs: Make sqlhist parser reentrant

Message ID 20210730221824.595597-8-rostedt@goodmis.org
State New
Headers show
Series libtracefs: Introducing tracefs_sql() to create synthetice events with an SQL line | expand

Commit Message

Steven Rostedt July 30, 2021, 10:18 p.m. UTC
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

Update bison and flex to be reentrant, and not depend on any global
variables.

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 src/sqlhist-parse.h   |  3 +--
 src/sqlhist.l         | 26 ++++++++++++++++----------
 src/sqlhist.y         | 10 ++++++++--
 src/tracefs-sqlhist.c | 41 ++++++++++++++++++++++++-----------------
 4 files changed, 49 insertions(+), 31 deletions(-)
diff mbox series

Patch

diff --git a/src/sqlhist-parse.h b/src/sqlhist-parse.h
index 0933bfe9a574..7c1b97ca65af 100644
--- a/src/sqlhist-parse.h
+++ b/src/sqlhist-parse.h
@@ -10,6 +10,7 @@  struct str_hash;
 struct sql_table;
 
 struct sqlhist_bison {
+	void			*scanner;
 	const char		*buffer;
 	size_t			buffer_size;
 	size_t			buffer_idx;
@@ -20,8 +21,6 @@  struct sqlhist_bison {
 	struct str_hash         *str_hash[1 << HASH_BITS];
 };
 
-extern struct sqlhist_bison *sb;
-
 #include "sqlhist.tab.h"
 
 enum filter_type {
diff --git a/src/sqlhist.l b/src/sqlhist.l
index 476f7fd1f1ec..958c46051148 100644
--- a/src/sqlhist.l
+++ b/src/sqlhist.l
@@ -4,21 +4,26 @@ 
 #include <stdarg.h>
 #include "sqlhist-parse.h"
 
-extern int my_yyinput(char *buf, int max);
+extern int my_yyinput(void *extra, char *buf, int max);
 
 #undef YY_INPUT
-#define YY_INPUT(b, r, m) ({r = my_yyinput(b, m);})
+#define YY_INPUT(b, r, m) ({r = my_yyinput(yyextra, b, m);})
 
 #define YY_NO_INPUT
 #define YY_NO_UNPUT
 
 #define YY_EXTRA_TYPE struct sqlhist_bison *
 
-#define HANDLE_COLUMN do { sb->line_idx += strlen(yytext); } while (0)
+#define yytext yyg->yytext_r
+
+#define TRACE_SB	((struct sqlhist_bison *)yyextra)
+#define HANDLE_COLUMN do { TRACE_SB->line_idx += strlen(yytext); } while (0)
 
 %}
 
 %option caseless
+%option reentrant
+%option bison-bridge
 
 field		[a-z_][a-z0-9_\.]*
 qstring		\"[^\"]*\"
@@ -36,25 +41,25 @@  where { HANDLE_COLUMN; return WHERE; }
 
 {qstring} {
 	HANDLE_COLUMN;
-	yylval.string = store_str(sb, yytext);
+	yylval->string = store_str(TRACE_SB, yyg->yytext_r);
 	return STRING;
 }
 
 {field} {
 	HANDLE_COLUMN;
-	yylval.string = store_str(sb, yytext);
+	yylval->string = store_str(TRACE_SB, yyg->yytext_r);
 	return FIELD;
 }
 
 {hexnum} {
 	HANDLE_COLUMN;
-	yylval.number = strtol(yytext, NULL, 0);
+	yylval->number = strtol(yyg->yytext_r, NULL, 0);
 	return NUMBER;
 }
 
 {number} {
 	HANDLE_COLUMN;
-	yylval.number = strtol(yytext, NULL, 0);
+	yylval->number = strtol(yyg->yytext_r, NULL, 0);
 	return NUMBER;
 }
 
@@ -69,18 +74,19 @@  where { HANDLE_COLUMN; return WHERE; }
 [\!()\-\+\*/,=] { HANDLE_COLUMN; return yytext[0]; }
 
 [ \t] { HANDLE_COLUMN; }
-\n { sb->line_idx = 0; sb->line_no++; }
+\n { TRACE_SB->line_idx = 0; TRACE_SB->line_no++; }
 
 . { HANDLE_COLUMN; return PARSE_ERROR; }
 %%
 
-int yywrap(void)
+int yywrap(void *data)
 {
 	return 1;
 }
 
-void yyerror(const char *fmt, ...)
+void yyerror(struct sqlhist_bison *sb, char *fmt, ...)
 {
+	struct yyguts_t * yyg = (struct yyguts_t*)sb->scanner;
 	va_list ap;
 
 	va_start(ap, fmt);
diff --git a/src/sqlhist.y b/src/sqlhist.y
index 8dcc824bb9f1..ce9cb58fb3a9 100644
--- a/src/sqlhist.y
+++ b/src/sqlhist.y
@@ -6,8 +6,10 @@ 
 
 #include "sqlhist-parse.h"
 
-extern int yylex(void);
-extern void yyerror(char *fmt, ...);
+#define scanner sb->scanner
+
+extern int yylex(YYSTYPE *yylval, void *);
+extern void yyerror(struct sqlhist_bison *, char *fmt, ...);
 
 #define CHECK_RETURN_PTR(x)					\
 	do {							\
@@ -27,6 +29,10 @@  extern void yyerror(char *fmt, ...);
 
 %}
 
+%define api.pure
+%lex-param {void *scanner}
+%parse-param {struct sqlhist_bison *sb}
+
 %union {
 	int	s32;
 	char	*string;
diff --git a/src/tracefs-sqlhist.c b/src/tracefs-sqlhist.c
index e47bc57c5add..e8f77d60659f 100644
--- a/src/tracefs-sqlhist.c
+++ b/src/tracefs-sqlhist.c
@@ -14,8 +14,6 @@ 
 #include "tracefs-local.h"
 #include "sqlhist-parse.h"
 
-struct sqlhist_bison *sb;
-
 extern int yylex_init(void* ptr_yy_globals);
 extern int yylex_init_extra(struct sqlhist_bison *sb, void* ptr_yy_globals);
 extern int yylex_destroy (void * yyscanner );
@@ -98,8 +96,10 @@  struct sql_table {
 	struct expr		**next_selection;
 };
 
-__hidden int my_yyinput(char *buf, int max)
+__hidden int my_yyinput(void *extra, char *buf, int max)
 {
+	struct sqlhist_bison *sb = extra;
+
 	if (!sb || !sb->buffer)
 		return -1;
 
@@ -284,7 +284,8 @@  static struct expr *find_field(struct sqlhist_bison *sb,
 	return NULL;
 }
 
-static void *create_expr(enum expr_type type, struct expr **expr_p)
+static void *create_expr(struct sqlhist_bison *sb,
+			 enum expr_type type, struct expr **expr_p)
 {
 	struct expr *expr;
 
@@ -313,7 +314,7 @@  static void *create_expr(enum expr_type type, struct expr **expr_p)
 
 #define __create_expr(var, type, ENUM, expr)			\
 	do {							\
-		var = (type *)create_expr(EXPR_##ENUM, expr);	\
+		var = (type *)create_expr(sb, EXPR_##ENUM, expr);	\
 	} while(0)
 
 #define create_field(var, expr)				\
@@ -999,8 +1000,8 @@  static void free_sb(struct sqlhist_bison *sb)
 struct tracefs_synth *tracefs_sql(struct tep_handle *tep, const char *name,
 				  const char *sql_buffer, char **err)
 {
-	struct sqlhist_bison local_sb;
 	struct tracefs_synth *synth = NULL;
+	struct sqlhist_bison sb;
 	int ret;
 
 	if (!tep || !sql_buffer) {
@@ -1008,27 +1009,33 @@  struct tracefs_synth *tracefs_sql(struct tep_handle *tep, const char *name,
 		return NULL;
 	}
 
-	memset(&local_sb, 0, sizeof(local_sb));
+	memset(&sb, 0, sizeof(sb));
+
+	sb.buffer = sql_buffer;
+	sb.buffer_size = strlen(sql_buffer);
+	sb.buffer_idx = 0;
 
-	local_sb.buffer = sql_buffer;
-	local_sb.buffer_size = strlen(sql_buffer);
-	local_sb.buffer_idx = 0;
+	ret = yylex_init_extra(&sb, &sb.scanner);
+	if (ret < 0) {
+		yylex_destroy(sb.scanner);
+		return NULL;
+	}
 
-	sb = &local_sb;
-	ret = yyparse();
+	ret = yyparse(&sb);
+	yylex_destroy(sb.scanner);
 
 	if (ret)
 		goto free;
 
-	synth = build_synth(tep, name, sb->table);
+	synth = build_synth(tep, name, sb.table);
 
  free:
 	if (!synth) {
-		if (sb->parse_error_str && err) {
-			*err = sb->parse_error_str;
-			sb->parse_error_str = NULL;
+		if (sb.parse_error_str && err) {
+			*err = sb.parse_error_str;
+			sb.parse_error_str = NULL;
 		}
 	}
-	free_sb(sb);
+	free_sb(&sb);
 	return synth;
 }