Skip to content

Commit

Permalink
Simplify lexer and parser API using fmemopen()
Browse files Browse the repository at this point in the history
This patch is a refactor of the parser interface to the lexical
analyzer.  Prior to this patch the lexer had two entry points,
one for file based access and one for buffer based access.

The lexer is better suited for file operations and by using the
fmemopen() API (POSIX 2008) buffers can be accessed in the same
manner as a file.

The resulting code is less complex and is further simplified and
fixed (for leaks) in the following commit(s).

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
  • Loading branch information
troglobit committed Dec 14, 2016
1 parent 81d79d6 commit 9060af0
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 40 deletions.
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ AC_CHECK_HEADERS([sys/stat.h])
AC_C_CONST

# Checks for library functions.
AC_CHECK_FUNCS([strcasecmp strdup strndup setenv unsetenv _putenv])
AC_CHECK_FUNCS([fmemopen strcasecmp strdup strndup setenv unsetenv _putenv])

AC_CONFIG_FILES([Makefile \
src/Makefile \
Expand Down
39 changes: 24 additions & 15 deletions src/confuse.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@

extern int cfg_yylex(cfg_t *cfg);
extern int cfg_lexer_include(cfg_t *cfg, const char *fname);
extern void cfg_scan_string_begin(const char *buf);
extern void cfg_scan_string_end(void);
extern void cfg_scan_fp_begin(FILE *fp);
extern void cfg_scan_fp_end(void);
extern char *cfg_qstring;
Expand Down Expand Up @@ -556,6 +554,7 @@ static void cfg_init_defaults(cfg_t *cfg)
if (is_set(CFGF_LIST, cfg->opts[i].flags) || cfg->opts[i].def.parsed) {
int xstate, ret;
char *buf;
FILE *fp;

/* If it's a list, but no default value was given,
* keep the option uninitialized.
Expand All @@ -576,12 +575,20 @@ static void cfg_init_defaults(cfg_t *cfg)
else
xstate = 2;

cfg_scan_string_begin(cfg->opts[i].def.parsed);
do {
ret = cfg_parse_internal(cfg, 1, xstate, &cfg->opts[i]);
xstate = -1;
} while (ret == STATE_CONTINUE);
cfg_scan_string_end();
fp = fmemopen(buf, strlen(buf), "r");
if (!fp) {
ret = STATE_ERROR;
} else {
cfg_scan_fp_begin(fp);

do {
ret = cfg_parse_internal(cfg, 1, xstate, &cfg->opts[i]);
xstate = -1;
} while (ret == STATE_CONTINUE);

cfg_scan_fp_end();
fclose(fp);
}

if (ret == STATE_ERROR) {
/*
Expand Down Expand Up @@ -1379,6 +1386,7 @@ DLLIMPORT int cfg_parse(cfg_t *cfg, const char *filename)
fn = cfg_tilde_expand(filename);
if (!fn)
return CFG_FILE_ERROR;

free(cfg->filename);
cfg->filename = fn;

Expand All @@ -1396,6 +1404,7 @@ DLLIMPORT int cfg_parse_buf(cfg_t *cfg, const char *buf)
{
int ret;
char *fn;
FILE *fp;

if (!cfg) {
errno = EINVAL;
Expand All @@ -1412,14 +1421,14 @@ DLLIMPORT int cfg_parse_buf(cfg_t *cfg, const char *buf)
free(cfg->filename);
cfg->filename = fn;

cfg->line = 1;
cfg_scan_string_begin(buf);
ret = cfg_parse_internal(cfg, 0, -1, 0);
cfg_scan_string_end();
if (ret == STATE_ERROR)
return CFG_PARSE_ERROR;
fp = fmemopen((void *)buf, strlen(buf), "r");
if (!fp)
return CFG_FILE_ERROR;

return CFG_SUCCESS;
ret = cfg_parse_fp(cfg, fp);
fclose(fp);

return ret;
}

DLLIMPORT cfg_t *cfg_init(cfg_opt_t *opts, cfg_flag_t flags)
Expand Down
24 changes: 0 additions & 24 deletions src/lexer.l
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ struct {
} cfg_include_stack[MAX_INCLUDE_DEPTH];
int cfg_include_stack_ptr = 0;

static YY_BUFFER_STATE pre_string_scan_state = 0;
static YY_BUFFER_STATE string_scan_state = 0;

%}

Expand Down Expand Up @@ -353,28 +351,6 @@ static void qputc(char ch)
cfg_qstring[qstring_index++] = ch;
}

void cfg_scan_string_begin(const char *buf)
{
pre_string_scan_state = YY_CURRENT_BUFFER;

/* yy_scan_string does a yy_switch_to_buffer call for us
*/
string_scan_state = yy_scan_string(buf);
}

void cfg_scan_string_end(void)
{
/* restore to previous state
*/
yy_delete_buffer(string_scan_state);
if (pre_string_scan_state)
yy_switch_to_buffer(pre_string_scan_state);
free(cfg_qstring);
cfg_qstring = 0;
qstring_index = qstring_len = 0;
string_scan_state = 0;
}

static YY_BUFFER_STATE pre_fp_scan_state;
static YY_BUFFER_STATE fp_scan_state;

Expand Down

0 comments on commit 9060af0

Please sign in to comment.