summaryrefslogtreecommitdiffstats
path: root/cmd-parse.y
diff options
context:
space:
mode:
authornicm <nicm>2019-05-26 10:08:50 +0000
committernicm <nicm>2019-05-26 10:08:50 +0000
commit6dee40998112d53b89c8e82f46701ee6a9ce62e6 (patch)
tree5167160a8ce79c0f07e54deaa8134306e3ef7c4c /cmd-parse.y
parenta65a6d62d19136e20ce6e6ec72d676a334dcc914 (diff)
Some other platforms doesn't support fmemopen(3) (not unexpectedly), so
don't use it - since we only use getc/ungetc on the file anyway it is easy not to.
Diffstat (limited to 'cmd-parse.y')
-rw-r--r--cmd-parse.y127
1 files changed, 76 insertions, 51 deletions
diff --git a/cmd-parse.y b/cmd-parse.y
index be7c0039..43ec8a94 100644
--- a/cmd-parse.y
+++ b/cmd-parse.y
@@ -53,6 +53,11 @@ TAILQ_HEAD(cmd_parse_commands, cmd_parse_command);
struct cmd_parse_state {
FILE *f;
+
+ const char *buf;
+ size_t len;
+ size_t off;
+
int eof;
struct cmd_parse_input *input;
u_int escapes;
@@ -66,7 +71,6 @@ struct cmd_parse_state {
static struct cmd_parse_state parse_state;
static char *cmd_parse_get_error(const char *, u_int, const char *);
-static char *cmd_parse_get_strerror(const char *, u_int);
static void cmd_parse_free_command(struct cmd_parse_command *);
static void cmd_parse_free_commands(struct cmd_parse_commands *);
@@ -483,12 +487,6 @@ cmd_parse_get_error(const char *file, u_int line, const char *error)
return (s);
}
-static char *
-cmd_parse_get_strerror(const char *file, u_int line)
-{
- return (cmd_parse_get_error(file, line, strerror(errno)));
-}
-
static void
cmd_parse_free_command(struct cmd_parse_command *cmd)
{
@@ -509,19 +507,13 @@ cmd_parse_free_commands(struct cmd_parse_commands *cmds)
}
static struct cmd_parse_commands *
-cmd_parse_run_parser(FILE *f, struct cmd_parse_input *pi, char **cause)
+cmd_parse_run_parser(char **cause)
{
struct cmd_parse_state *ps = &parse_state;
struct cmd_parse_commands *cmds;
struct cmd_parse_scope *scope, *scope1;
int retval;
- memset(ps, 0, sizeof *ps);
-
- ps->f = f;
- ps->eof = 0;
- ps->input = pi;
-
TAILQ_INIT(&ps->commands);
TAILQ_INIT(&ps->stack);
@@ -541,6 +533,30 @@ cmd_parse_run_parser(FILE *f, struct cmd_parse_input *pi, char **cause)
return (cmds);
}
+static struct cmd_parse_commands *
+cmd_parse_do_file(FILE *f, struct cmd_parse_input *pi, char **cause)
+{
+ struct cmd_parse_state *ps = &parse_state;
+
+ memset(ps, 0, sizeof *ps);
+ ps->input = pi;
+ ps->f = f;
+ return (cmd_parse_run_parser(cause));
+}
+
+static struct cmd_parse_commands *
+cmd_parse_do_buffer(const char *buf, size_t len, struct cmd_parse_input *pi,
+ char **cause)
+{
+ struct cmd_parse_state *ps = &parse_state;
+
+ memset(ps, 0, sizeof *ps);
+ ps->input = pi;
+ ps->buf = buf;
+ ps->len = len;
+ return (cmd_parse_run_parser(cause));
+}
+
static struct cmd_parse_result *
cmd_parse_build_commands(struct cmd_parse_commands *cmds,
struct cmd_parse_input *pi)
@@ -548,7 +564,6 @@ cmd_parse_build_commands(struct cmd_parse_commands *cmds,
static struct cmd_parse_result pr;
struct cmd_parse_commands *cmds2;
struct cmd_parse_command *cmd, *cmd2, *next, *next2, *after;
- FILE *f;
u_int line = UINT_MAX;
int i;
struct cmd_list *cmdlist = NULL, *result;
@@ -576,16 +591,8 @@ cmd_parse_build_commands(struct cmd_parse_commands *cmds,
line = cmd->line;
log_debug("%s: %u %s = %s", __func__, line, cmd->name, alias);
- f = fmemopen(alias, strlen(alias), "r");
- if (f == NULL) {
- free(alias);
- pr.status = CMD_PARSE_ERROR;
- pr.error = cmd_parse_get_strerror(pi->file, line);
- goto out;
- }
pi->line = line;
- cmds2 = cmd_parse_run_parser(f, pi, &cause);
- fclose(f);
+ cmds2 = cmd_parse_do_buffer(alias, strlen(alias), pi, &cause);
free(alias);
if (cmds2 == NULL) {
pr.status = CMD_PARSE_ERROR;
@@ -678,10 +685,7 @@ cmd_parse_from_file(FILE *f, struct cmd_parse_input *pi)
}
memset(&pr, 0, sizeof pr);
- /*
- * Parse the file into a list of commands.
- */
- cmds = cmd_parse_run_parser(f, pi, &cause);
+ cmds = cmd_parse_do_file(f, pi, &cause);
if (cmds == NULL) {
pr.status = CMD_PARSE_ERROR;
pr.error = cause;
@@ -694,9 +698,9 @@ struct cmd_parse_result *
cmd_parse_from_string(const char *s, struct cmd_parse_input *pi)
{
static struct cmd_parse_result pr;
- struct cmd_parse_result *prp;
struct cmd_parse_input input;
- FILE *f;
+ struct cmd_parse_commands *cmds;
+ char *cause;
if (pi == NULL) {
memset(&input, 0, sizeof input);
@@ -711,16 +715,13 @@ cmd_parse_from_string(const char *s, struct cmd_parse_input *pi)
return (&pr);
}
- f = fmemopen((void *)s, strlen(s), "r");
- if (f == NULL) {
+ cmds = cmd_parse_do_buffer(s, strlen(s), pi, &cause);
+ if (cmds == NULL) {
pr.status = CMD_PARSE_ERROR;
- pr.cmdlist = NULL;
- pr.error = cmd_parse_get_strerror(pi->file, pi->line);
- return (NULL);
+ pr.error = cause;
+ return (&pr);
}
- prp = cmd_parse_from_file(f, pi);
- fclose(f);
- return (prp);
+ return (cmd_parse_build_commands(cmds, pi));
}
struct cmd_parse_result *
@@ -848,6 +849,34 @@ yylex_append1(char **buf, size_t *len, char add)
}
static int
+yylex_getc1(void)
+{
+ struct cmd_parse_state *ps = &parse_state;
+ int ch;
+
+ if (ps->f != NULL)
+ ch = getc(ps->f);
+ else {
+ if (ps->off == ps->len)
+ ch = EOF;
+ else
+ ch = ps->buf[ps->off++];
+ }
+ return (ch);
+}
+
+static void
+yylex_ungetc(int ch)
+{
+ struct cmd_parse_state *ps = &parse_state;
+
+ if (ps->f != NULL)
+ ungetc(ch, ps->f);
+ else if (ps->off > 0 && ch != EOF)
+ ps->off--;
+}
+
+static int
yylex_getc(void)
{
struct cmd_parse_state *ps = &parse_state;
@@ -858,7 +887,7 @@ yylex_getc(void)
return ('\\');
}
for (;;) {
- ch = getc(ps->f);
+ ch = yylex_getc1();
if (ch == '\\') {
ps->escapes++;
continue;
@@ -870,7 +899,7 @@ yylex_getc(void)
}
if (ps->escapes != 0) {
- ungetc(ch, ps->f);
+ yylex_ungetc(ch);
ps->escapes--;
return ('\\');
}
@@ -881,9 +910,8 @@ yylex_getc(void)
static char *
yylex_get_word(int ch)
{
- struct cmd_parse_state *ps = &parse_state;
- char *buf;
- size_t len;
+ char *buf;
+ size_t len;
len = 0;
buf = xmalloc(1);
@@ -891,7 +919,7 @@ yylex_get_word(int ch)
do
yylex_append1(&buf, &len, ch);
while ((ch = yylex_getc()) != EOF && strchr(" \t\n", ch) == NULL);
- ungetc(ch, ps->f);
+ yylex_ungetc(ch);
buf[len] = '\0';
log_debug("%s: %s", __func__, buf);
@@ -1117,7 +1145,6 @@ unicode:
static int
yylex_token_variable(char **buf, size_t *len)
{
- struct cmd_parse_state *ps = &parse_state;
struct environ_entry *envent;
int ch, brackets = 0;
char name[BUFSIZ];
@@ -1132,7 +1159,7 @@ yylex_token_variable(char **buf, size_t *len)
else {
if (!yylex_is_var(ch, 1)) {
yylex_append1(buf, len, '$');
- ungetc(ch, ps->f);
+ yylex_ungetc(ch);
return (1);
}
name[namelen++] = ch;
@@ -1144,7 +1171,7 @@ yylex_token_variable(char **buf, size_t *len)
break;
if (ch == EOF || !yylex_is_var(ch, 0)) {
if (!brackets) {
- ungetc(ch, ps->f);
+ yylex_ungetc(ch);
break;
}
yyerror("invalid environment variable");
@@ -1170,7 +1197,6 @@ yylex_token_variable(char **buf, size_t *len)
static int
yylex_token_tilde(char **buf, size_t *len)
{
- struct cmd_parse_state *ps = &parse_state;
struct environ_entry *envent;
int ch;
char name[BUFSIZ];
@@ -1181,7 +1207,7 @@ yylex_token_tilde(char **buf, size_t *len)
for (;;) {
ch = yylex_getc();
if (ch == EOF || strchr("/ \t\n\"'", ch) != NULL) {
- ungetc(ch, ps->f);
+ yylex_ungetc(ch);
break;
}
if (namelen == (sizeof name) - 2) {
@@ -1213,7 +1239,6 @@ yylex_token_tilde(char **buf, size_t *len)
static char *
yylex_token(int ch)
{
- struct cmd_parse_state *ps = &parse_state;
char *buf;
size_t len;
enum { START,
@@ -1293,7 +1318,7 @@ yylex_token(int ch)
next:
ch = yylex_getc();
}
- ungetc(ch, ps->f);
+ yylex_ungetc(ch);
buf[len] = '\0';
log_debug("%s: %s", __func__, buf);