X-Git-Url: http://git.tuebingen.mpg.de/?p=lopsub.git;a=blobdiff_plain;f=config_file.l;h=d0555994cce46b6bb3f3e4204683f10442be0aa6;hp=b6eff7cc5bd09ae4f4d257ee76be4a4d9279e99e;hb=427af673591a006e351dcf76e5957ed67d4e0477;hpb=825083ef841055965335996771b385e4cb9c62ca diff --git a/config_file.l b/config_file.l index b6eff7c..d055599 100644 --- a/config_file.l +++ b/config_file.l @@ -7,6 +7,9 @@ /* We don't want symbols to clash with those of other flex users. */ %option prefix="lls_yy" + /* Generate a scanner which is safe to use in multithreaded programs. */ +%option reentrant + %option stack %option never-interactive %option yylineno @@ -31,100 +34,9 @@ OPTION [a-zA-Z]+[a-zA-Z0-9_-]* static char **rargv; static const char *subcommand; - static int yywrap(void) {return 1;} - static int expand_result(void) - { - int nargc = rargc + 1; - char **nrargv = realloc(rargv, (nargc + 1) * sizeof(char *)); - - if (!nrargv) - return -E_LLS_NOMEM; - rargc = nargc; - rargv = nrargv; - rargv[rargc] = NULL; - return 1; - } - - static int add_option(void) - { - int ret; - unsigned n; - - for (n = 0; n < yyleng; n++) - if (!isalnum(yytext[n]) && !(yytext[n] == '-')) - break; - assert(n > 0); - ret = expand_result(); - if (ret < 0) - return ret; - rargv[rargc - 1] = malloc(n + 2 + 1); - if (!rargv[rargc - 1]) - return -E_LLS_NOMEM; - rargv[rargc - 1][0] = rargv[rargc - 1][1] = '-'; - memcpy(rargv[rargc - 1] + 2, yytext, n); - rargv[rargc - 1][n + 2] = '\0'; - return 1; - } - - static int parse_arg(char **result) - { - bool backslash = false, quote = false; - const char *in; - char *out; - int ret; - - *result = malloc(yyleng + 1); - if (!*result) - return -E_LLS_NOMEM; - for (in = yytext, out = *result; *in; in++) { - if (*in == '\\') { - if (!backslash) { - backslash = true; - continue; - } - } else if (*in == 'n' || *in == 't') { - if (backslash) { /* \n or \t */ - *out++ = (*in == 'n')? '\n' : '\t'; - backslash = false; - continue; - } - } else if (*in == '"') { - if (!backslash) { - quote = !quote; - continue; - } - } else if (isspace(*in)) { - if (!backslash && !quote) - break; - } - /* copy the character */ - *out++ = *in; - backslash = false; - } - ret = -E_LLS_TRAILING_BACKSLASH; - if (backslash) - goto fail; - ret = -E_LLS_UNMATCHED_QUOTE; - if (quote) - goto fail; - /* look at first non-space character */ - for (; *in; in++) { - if (isspace(*in)) - continue; - if (*in == '#') - break; - ret = -E_LLS_TRAILING_GARBAGE; - goto fail; - } - /* success */ - *out = '\0'; - return out - *result; - fail: - assert(ret < 0); - free(*result); - *result = NULL; - return ret; - } + static int add_option(yyscan_t yyscanner); + static int parse_arg(char **result, yyscan_t yyscanner); + static int yywrap(yyscan_t yyscanner) {return 1;} %} %% @@ -153,10 +65,10 @@ OPTION [a-zA-Z]+[a-zA-Z0-9_-]* BEGIN(SC_SCANNING); } -{OPTION}[[:space:]]*\n add_option(); +{OPTION}[[:space:]]*\n add_option(yyscanner); {OPTION}({EQUALS}|[[:space:]]+) { - int ret = add_option(); + int ret = add_option(yyscanner); if (ret < 0) return ret; @@ -167,7 +79,7 @@ OPTION [a-zA-Z]+[a-zA-Z0-9_-]* const char *opt = rargv[rargc - 1]; char *arg, *result; size_t opt_len = strlen(opt), arg_len; - int ret = parse_arg(&arg); + int ret = parse_arg(&arg, yyscanner); if (ret < 0) return ret; @@ -196,21 +108,119 @@ OPTION [a-zA-Z]+[a-zA-Z0-9_-]* #include #include +static int expand_result(void) +{ + int nargc = rargc + 1; + char **nrargv = realloc(rargv, (nargc + 1) * sizeof(char *)); + + if (!nrargv) + return -E_LLS_NOMEM; + rargc = nargc; + rargv = nrargv; + rargv[rargc] = NULL; + return 1; +} + +static int add_option(yyscan_t yyscanner) +{ + int ret; + unsigned n; + int len = yyget_leng(yyscanner); + char *text = yyget_text(yyscanner); + + for (n = 0; n < len; n++) + if (!isalnum(text[n]) && !(text[n] == '-')) + break; + assert(n > 0); + ret = expand_result(); + if (ret < 0) + return ret; + rargv[rargc - 1] = malloc(n + 2 + 1); + if (!rargv[rargc - 1]) + return -E_LLS_NOMEM; + rargv[rargc - 1][0] = rargv[rargc - 1][1] = '-'; + memcpy(rargv[rargc - 1] + 2, text, n); + rargv[rargc - 1][n + 2] = '\0'; + return 1; +} + +static int parse_arg(char **result, yyscan_t yyscanner) +{ + bool backslash = false, quote = false; + const char *in; + char *out; + int ret; + int len = yyget_leng(yyscanner); + char *text = yyget_text(yyscanner); + + *result = malloc(len + 1); + if (!*result) + return -E_LLS_NOMEM; + for (in = text, out = *result; *in; in++) { + if (*in == '\\') { + if (!backslash) { + backslash = true; + continue; + } + } else if (*in == 'n' || *in == 't') { + if (backslash) { /* \n or \t */ + *out++ = (*in == 'n')? '\n' : '\t'; + backslash = false; + continue; + } + } else if (*in == '"') { + if (!backslash) { + quote = !quote; + continue; + } + } else if (isspace(*in)) { + if (!backslash && !quote) + break; + } + /* copy the character */ + *out++ = *in; + backslash = false; + } + ret = -E_LLS_TRAILING_BACKSLASH; + if (backslash) + goto fail; + ret = -E_LLS_UNMATCHED_QUOTE; + if (quote) + goto fail; + /* look at first non-space character */ + for (; *in; in++) { + if (isspace(*in)) + continue; + if (*in == '#') + break; + ret = -E_LLS_TRAILING_GARBAGE; + goto fail; + } + /* success */ + *out = '\0'; + return out - *result; +fail: + assert(ret < 0); + free(*result); + *result = NULL; + return ret; +} + int lls_convert_config(const char *buf, size_t nbytes, const char *subcmd, char ***result, char **errctx) { int ret; YY_BUFFER_STATE yybs; + yyscan_t yyscanner; *result = NULL; if (errctx) *errctx = NULL; + ret = yylex_init(&yyscanner); + assert(ret == 0); subcommand = subcmd; - if (!subcmd) - BEGIN(SC_SCANNING); - else - BEGIN(INITIAL); - yybs = yy_scan_bytes(buf, nbytes); + yy_push_state(subcmd? INITIAL : SC_SCANNING, yyscanner); + yybs = yy_scan_bytes(buf, nbytes, yyscanner); if (!yybs) return -E_LLS_YY_SCAN; rargc = 1; @@ -223,8 +233,9 @@ int lls_convert_config(const char *buf, size_t nbytes, const char *subcmd, return -E_LLS_NOMEM; } rargv[1] = NULL; - ret = yylex(); - yy_delete_buffer(yybs); + ret = yylex(yyscanner); + yy_delete_buffer(yybs, yyscanner); + yylex_destroy(yyscanner); if (ret >= 0) { *result = rargv; return rargc; @@ -232,7 +243,8 @@ int lls_convert_config(const char *buf, size_t nbytes, const char *subcmd, if (errctx) { *errctx = malloc(100); if (*errctx) - sprintf(*errctx, "error at line %d", yyget_lineno()); + sprintf(*errctx, "error at line %d", + yyget_lineno(yyscanner)); } for (; rargc >= 0; rargc--) free(rargv[rargc]);