aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2018-06-04 11:11:20 +0300
committerSergey Poznyakoff <gray@gnu.org>2018-06-04 11:11:20 +0300
commitc3850a4d3f94436aab6b23020242bc99c71506ee (patch)
tree644cd582c39c833124d1d071a4b7738bac97428d /src
parent43a1c4ce04cf9301b88c8df31087fe84dcb7e232 (diff)
downloadgrecs-c3850a4d3f94436aab6b23020242bc99c71506ee.tar.gz
grecs-c3850a4d3f94436aab6b23020242bc99c71506ee.tar.bz2
json: improve parser reentrability
* include/grecs/json.h (jsonlex_cleanup): New proto. * src/json-lex.l (jsonlex_setup): Initialize parser state. Initialize json_current_locus_point.file to a non-NULL value. (jsonlex_cleanup): New function. * src/json-gram.y (json_parse_string): Call jsonlex_cleanup before returning. * src/diag.c (default_print_diag): Print the passed errcode argument, instead of errno.
Diffstat (limited to 'src')
-rw-r--r--src/diag.c2
-rw-r--r--src/json-gram.y1
-rw-r--r--src/json-lex.l35
3 files changed, 25 insertions, 13 deletions
diff --git a/src/diag.c b/src/diag.c
index bdbb407..db96e75 100644
--- a/src/diag.c
+++ b/src/diag.c
@@ -28,25 +28,25 @@ default_print_diag(grecs_locus_t const *locus, int err, int errcode,
const char *msg)
{
fflush(stdout);
if (locus) {
YY_LOCATION_PRINT(stderr, *locus);
fputc(':', stderr);
fputc(' ', stderr);
}
if (!err)
fprintf(stderr, "warning: ");
fprintf(stderr, "%s", msg);
if (errcode)
- fprintf(stderr, ": %s", strerror(errno));
+ fprintf(stderr, ": %s", strerror(errcode));
fputc('\n', stderr);
}
void (*grecs_print_diag_fun)(grecs_locus_t const *, int, int,
const char *msg) =
default_print_diag;
void
grecs_warning(grecs_locus_t const *locus, int errcode, const char *fmt, ...)
{
va_list ap;
char *buf = NULL;
diff --git a/src/json-gram.y b/src/json-gram.y
index fe8996b..d5b0248 100644
--- a/src/json-gram.y
+++ b/src/json-gram.y
@@ -271,24 +271,25 @@ json_assoc_create()
NULL,
json_st_free);
}
struct json_value *
json_parse_string(char const *input, size_t len)
{
jsonlex_setup(input, len);
if (yyparse()) {
/* FIXME: error recovery */
return NULL;
}
+ jsonlex_cleanup();
return json_return_obj;
}
struct json_value *
json_value_lookup(struct json_value *obj, const char *ident)
{
char *qbuf = NULL;
size_t qlen = 0;
while (obj && *ident) {
char const *p;
char *q;
diff --git a/src/json-lex.l b/src/json-lex.l
index 169cf32..4bbdedf 100644
--- a/src/json-lex.l
+++ b/src/json-lex.l
@@ -46,36 +46,24 @@ struct grecs_locus json_err_locus;
} while(0)
#define YY_USER_ACTION do { \
if (YYSTATE == 0) { \
yylloc.beg = json_current_locus_point; \
yylloc.beg.col++; \
} \
json_current_locus_point.col += yyleng; \
yylloc.end = json_current_locus_point; \
} while (0);
void
-jsonlex_setup(char const *s, size_t l)
-{
- input_ptr = s;
- input_size = l;
- json_current_locus_point.file = NULL;
- json_current_locus_point.line = 1;
- json_current_locus_point.col = 0;
- json_err_diag = NULL;
- yy_flex_debug = 0;
-}
-
-void
jsonlex_diag(const char *s)
{
if (!json_err_diag) {
json_err_diag = s;
json_err_locus = yylloc;
}
}
static int
utf8_wctomb(char *u)
{
unsigned int wc = strtoul(u, NULL, 16);
@@ -218,12 +206,35 @@ X [0-9a-fA-F]
return T_ERR;
}
json_line_grow(&c, 1); }
null { return T_NULL; }
true { yylval.b = 1; return T_BOOL; }
false { yylval.b = 0; return T_BOOL; }
"{"|"}"|"["|"]"|":"|"," return yytext[0];
[ \t]* ;
\n grecs_locus_point_advance_line(json_current_locus_point);
. { jsonlex_diag("bogus character");
return T_ERR; }
+%%
+void
+jsonlex_setup(char const *s, size_t l)
+{
+ input_ptr = s;
+ input_size = l;
+ json_current_locus_point.file = "input";
+ json_current_locus_point.line = 1;
+ json_current_locus_point.col = 0;
+ json_err_diag = NULL;
+ yy_flex_debug = 0;
+ BEGIN(INITIAL);
+ yyrestart(NULL);
+}
+
+void
+jsonlex_cleanup(void)
+{
+ if (json_line_acc) {
+ grecs_txtacc_free(json_line_acc);
+ json_line_acc = NULL;
+ }
+}

Return to:

Send suggestions and report system problems to the System administrator.