=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/cmd-parse.y,v retrieving revision 1.4 retrieving revision 1.5 diff -c -r1.4 -r1.5 *** src/usr.bin/tmux/cmd-parse.y 2019/05/25 07:18:20 1.4 --- src/usr.bin/tmux/cmd-parse.y 2019/05/26 10:08:50 1.5 *************** *** 1,4 **** ! /* $OpenBSD: cmd-parse.y,v 1.4 2019/05/25 07:18:20 nicm Exp $ */ /* * Copyright (c) 2019 Nicholas Marriott --- 1,4 ---- ! /* $OpenBSD: cmd-parse.y,v 1.5 2019/05/26 10:08:50 nicm Exp $ */ /* * Copyright (c) 2019 Nicholas Marriott *************** *** 53,58 **** --- 53,63 ---- 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,72 **** 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 *); --- 71,76 ---- *************** *** 483,494 **** 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) { --- 487,492 ---- *************** *** 509,527 **** } static struct cmd_parse_commands * ! cmd_parse_run_parser(FILE *f, struct cmd_parse_input *pi, 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); --- 507,519 ---- } static struct cmd_parse_commands * ! 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; TAILQ_INIT(&ps->commands); TAILQ_INIT(&ps->stack); *************** *** 541,546 **** --- 533,562 ---- 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,554 **** 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; --- 564,569 ---- *************** *** 576,591 **** 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); free(alias); if (cmds2 == NULL) { pr.status = CMD_PARSE_ERROR; --- 591,598 ---- line = cmd->line; log_debug("%s: %u %s = %s", __func__, line, cmd->name, alias); pi->line = line; ! cmds2 = cmd_parse_do_buffer(alias, strlen(alias), pi, &cause); free(alias); if (cmds2 == NULL) { pr.status = CMD_PARSE_ERROR; *************** *** 678,687 **** } memset(&pr, 0, sizeof pr); ! /* ! * Parse the file into a list of commands. ! */ ! cmds = cmd_parse_run_parser(f, pi, &cause); if (cmds == NULL) { pr.status = CMD_PARSE_ERROR; pr.error = cause; --- 685,691 ---- } memset(&pr, 0, sizeof pr); ! cmds = cmd_parse_do_file(f, pi, &cause); if (cmds == NULL) { pr.status = CMD_PARSE_ERROR; pr.error = cause; *************** *** 694,702 **** 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; if (pi == NULL) { memset(&input, 0, sizeof input); --- 698,706 ---- cmd_parse_from_string(const char *s, struct cmd_parse_input *pi) { static struct cmd_parse_result pr; struct cmd_parse_input input; ! struct cmd_parse_commands *cmds; ! char *cause; if (pi == NULL) { memset(&input, 0, sizeof input); *************** *** 711,726 **** return (&pr); } ! f = fmemopen((void *)s, strlen(s), "r"); ! if (f == NULL) { pr.status = CMD_PARSE_ERROR; ! pr.cmdlist = NULL; ! pr.error = cmd_parse_get_strerror(pi->file, pi->line); ! return (NULL); } ! prp = cmd_parse_from_file(f, pi); ! fclose(f); ! return (prp); } struct cmd_parse_result * --- 715,727 ---- return (&pr); } ! cmds = cmd_parse_do_buffer(s, strlen(s), pi, &cause); ! if (cmds == NULL) { pr.status = CMD_PARSE_ERROR; ! pr.error = cause; ! return (&pr); } ! return (cmd_parse_build_commands(cmds, pi)); } struct cmd_parse_result * *************** *** 848,853 **** --- 849,882 ---- } 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,864 **** return ('\\'); } for (;;) { ! ch = getc(ps->f); if (ch == '\\') { ps->escapes++; continue; --- 887,893 ---- return ('\\'); } for (;;) { ! ch = yylex_getc1(); if (ch == '\\') { ps->escapes++; continue; *************** *** 870,876 **** } if (ps->escapes != 0) { ! ungetc(ch, ps->f); ps->escapes--; return ('\\'); } --- 899,905 ---- } if (ps->escapes != 0) { ! yylex_ungetc(ch); ps->escapes--; return ('\\'); } *************** *** 881,889 **** static char * yylex_get_word(int ch) { ! struct cmd_parse_state *ps = &parse_state; ! char *buf; ! size_t len; len = 0; buf = xmalloc(1); --- 910,917 ---- static char * yylex_get_word(int ch) { ! char *buf; ! size_t len; len = 0; buf = xmalloc(1); *************** *** 891,897 **** do yylex_append1(&buf, &len, ch); while ((ch = yylex_getc()) != EOF && strchr(" \t\n", ch) == NULL); ! ungetc(ch, ps->f); buf[len] = '\0'; log_debug("%s: %s", __func__, buf); --- 919,925 ---- do yylex_append1(&buf, &len, ch); while ((ch = yylex_getc()) != EOF && strchr(" \t\n", ch) == NULL); ! yylex_ungetc(ch); buf[len] = '\0'; log_debug("%s: %s", __func__, buf); *************** *** 1117,1123 **** 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]; --- 1145,1150 ---- *************** *** 1132,1138 **** else { if (!yylex_is_var(ch, 1)) { yylex_append1(buf, len, '$'); ! ungetc(ch, ps->f); return (1); } name[namelen++] = ch; --- 1159,1165 ---- else { if (!yylex_is_var(ch, 1)) { yylex_append1(buf, len, '$'); ! yylex_ungetc(ch); return (1); } name[namelen++] = ch; *************** *** 1144,1150 **** break; if (ch == EOF || !yylex_is_var(ch, 0)) { if (!brackets) { ! ungetc(ch, ps->f); break; } yyerror("invalid environment variable"); --- 1171,1177 ---- break; if (ch == EOF || !yylex_is_var(ch, 0)) { if (!brackets) { ! yylex_ungetc(ch); break; } yyerror("invalid environment variable"); *************** *** 1170,1176 **** 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]; --- 1197,1202 ---- *************** *** 1181,1187 **** for (;;) { ch = yylex_getc(); if (ch == EOF || strchr("/ \t\n\"'", ch) != NULL) { ! ungetc(ch, ps->f); break; } if (namelen == (sizeof name) - 2) { --- 1207,1213 ---- for (;;) { ch = yylex_getc(); if (ch == EOF || strchr("/ \t\n\"'", ch) != NULL) { ! yylex_ungetc(ch); break; } if (namelen == (sizeof name) - 2) { *************** *** 1213,1219 **** static char * yylex_token(int ch) { - struct cmd_parse_state *ps = &parse_state; char *buf; size_t len; enum { START, --- 1239,1244 ---- *************** *** 1293,1299 **** next: ch = yylex_getc(); } ! ungetc(ch, ps->f); buf[len] = '\0'; log_debug("%s: %s", __func__, buf); --- 1318,1324 ---- next: ch = yylex_getc(); } ! yylex_ungetc(ch); buf[len] = '\0'; log_debug("%s: %s", __func__, buf);