tmux  3.2a
About: tmux is a terminal multiplexer that lets you switch easily between several programs in one terminal.
  Fossies Dox: tmux-3.2a.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

cmd-parse.c
Go to the documentation of this file.
1 #include <stdlib.h>
2 #include <string.h>
3 #define YYBYACC 1
4 #define YYMAJOR 1
5 #define YYMINOR 9
6 #define YYLEX yylex()
7 #define YYEMPTY -1
8 #define yyclearin (yychar=(YYEMPTY))
9 #define yyerrok (yyerrflag=0)
10 #define YYRECOVERING() (yyerrflag!=0)
11 #define YYPREFIX "yy"
12 #line 20 "cmd-parse.y"
13 
14 #include <sys/types.h>
15 
16 #include <ctype.h>
17 #include <errno.h>
18 #include <pwd.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <unistd.h>
22 #include <wchar.h>
23 
24 #include "tmux.h"
25 
26 static int yylex(void);
27 static int yyparse(void);
28 static int printflike(1,2) yyerror(const char *, ...);
29 
30 static char *yylex_token(int);
31 static char *yylex_format(void);
32 
34  int flag;
35  TAILQ_ENTRY (cmd_parse_scope) entry;
36 };
37 
39  u_int line;
40 
41  int argc;
42  char **argv;
43 
44  TAILQ_ENTRY(cmd_parse_command) entry;
45 };
46 TAILQ_HEAD(cmd_parse_commands, cmd_parse_command);
47 
49  FILE *f;
50 
51  const char *buf;
52  size_t len;
53  size_t off;
54 
55  int condition;
56  int eol;
57  int eof;
59  u_int escapes;
60 
61  char *error;
62  struct cmd_parse_commands *commands;
63 
65  TAILQ_HEAD(, cmd_parse_scope) stack;
66 };
67 static struct cmd_parse_state parse_state;
68 
69 static char *cmd_parse_get_error(const char *, u_int, const char *);
70 static void cmd_parse_free_command(struct cmd_parse_command *);
71 static struct cmd_parse_commands *cmd_parse_new_commands(void);
72 static void cmd_parse_free_commands(struct cmd_parse_commands *);
73 static char *cmd_parse_commands_to_string(struct cmd_parse_commands *);
74 static void cmd_parse_print_commands(struct cmd_parse_input *, u_int,
75  struct cmd_list *);
76 
77 #line 86 "cmd-parse.y"
78 #ifndef YYSTYPE_DEFINED
79 #define YYSTYPE_DEFINED
80 typedef union
81 {
82  char *token;
83  struct {
84  int argc;
85  char **argv;
86  } arguments;
87  int flag;
88  struct {
89  int flag;
90  struct cmd_parse_commands *commands;
91  } elif;
92  struct cmd_parse_commands *commands;
94 } YYSTYPE;
95 #endif /* YYSTYPE_DEFINED */
96 #line 97 "cmd-parse.c"
97 #define ERROR 257
98 #define HIDDEN 258
99 #define IF 259
100 #define ELSE 260
101 #define ELIF 261
102 #define ENDIF 262
103 #define FORMAT 263
104 #define TOKEN 264
105 #define EQUALS 265
106 #define YYERRCODE 256
107 const short yylhs[] =
108  { -1,
109  0, 0, 10, 10, 11, 11, 11, 11, 3, 3,
110  2, 17, 17, 18, 16, 5, 19, 6, 20, 13,
111  13, 13, 13, 7, 7, 12, 12, 12, 12, 12,
112  15, 15, 15, 14, 14, 14, 14, 8, 8, 4,
113  4, 1, 1, 1, 9, 9,
114 };
115 const short yylen[] =
116  { 2,
117  0, 1, 2, 3, 0, 1, 1, 1, 1, 1,
118  1, 0, 1, 1, 2, 2, 1, 2, 1, 4,
119  7, 5, 8, 3, 4, 1, 2, 3, 3, 1,
120  1, 2, 3, 3, 5, 4, 6, 2, 3, 1,
121  2, 1, 1, 2, 2, 3,
122 };
123 const short yydefred[] =
124  { 0,
125  0, 0, 14, 0, 0, 0, 0, 0, 7, 30,
126  26, 6, 0, 0, 15, 9, 10, 16, 11, 0,
127  0, 0, 0, 3, 0, 0, 0, 17, 0, 19,
128  0, 0, 0, 34, 4, 28, 29, 42, 43, 0,
129  0, 33, 0, 0, 0, 20, 18, 0, 0, 36,
130  0, 44, 0, 0, 41, 0, 0, 22, 0, 39,
131  0, 35, 0, 45, 0, 0, 0, 37, 46, 25,
132  0, 21, 23,
133 };
134 const short yydgoto[] =
135  { 4,
136  41, 18, 19, 42, 5, 31, 44, 32, 52, 6,
137  7, 8, 9, 10, 11, 12, 13, 14, 33, 34,
138 };
139 const short yysindex[] =
140  { -175,
141  -227, -172, 0, 0, -10, -175, 46, 10, 0, 0,
142  0, 0, -205, 0, 0, 0, 0, 0, 0, -175,
143  -238, -56, 53, 0, -238, -118, -228, 0, -172, 0,
144  -238, -234, -238, 0, 0, 0, 0, 0, 0, -175,
145  -118, 0, 63, -234, 66, 0, 0, -52, -238, 0,
146  -55, 0, -175, 3, 0, -175, 68, 0, -175, 0,
147  -55, 0, 4, 0, -208, -175, -219, 0, 0, 0,
148  -219, 0, 0,};
149 const short yyrindex[] =
150  { 1,
151  0, 0, 0, 0, -184, 2, 0, 5, 0, 0,
152  0, 0, 0, -4, 0, 0, 0, 0, 0, 6,
153  -184, 0, 0, 0, 7, 12, 6, 0, 0, 0,
154  -184, 0, -184, 0, 0, 0, 0, 0, 0, -2,
155  15, 0, 0, 0, 0, 0, 0, -215, -184, 0,
156  0, 0, -2, 0, 0, 6, 0, 0, 6, 0,
157  0, 0, 0, 0, -1, 6, 6, 0, 0, 0,
158  6, 0, 0,};
159 const short yygindex[] =
160  { 0,
161  0, 57, 0, 41, 39, -17, 28, 47, 0, 9,
162  14, 56, 0, 69, 71, 0, 0, 0, -8, -9,
163 };
164 #define YYTABLESIZE 277
165 const short yytable[] =
166  { 20,
167  1, 2, 25, 25, 40, 31, 25, 5, 5, 43,
168  5, 5, 24, 35, 8, 5, 27, 46, 45, 23,
169  2, 32, 50, 49, 40, 28, 3, 30, 27, 1,
170  2, 28, 29, 30, 58, 57, 3, 15, 1, 2,
171  23, 62, 30, 21, 38, 3, 38, 43, 53, 1,
172  2, 68, 29, 54, 31, 24, 3, 72, 26, 21,
173  22, 73, 35, 21, 65, 27, 63, 67, 25, 21,
174  32, 21, 56, 40, 71, 59, 22, 66, 23, 12,
175  23, 55, 1, 2, 23, 47, 48, 21, 51, 3,
176  16, 17, 70, 36, 60, 37, 0, 0, 0, 0,
177  0, 0, 0, 0, 61, 0, 0, 0, 0, 0,
178  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
179  31, 0, 5, 0, 0, 0, 0, 64, 69, 8,
180  0, 27, 0, 0, 0, 0, 32, 0, 0, 40,
181  0, 0, 0, 0, 0, 38, 39, 0, 0, 0,
182  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
183  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
184  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
185  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
186  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
187  0, 0, 0, 28, 29, 30, 30, 0, 29, 0,
188  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
189  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
190  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
191  0, 0, 0, 0, 0, 0, 0, 0, 2, 0,
192  0, 0, 0, 0, 3, 31, 31, 31, 24, 13,
193  24, 12, 12, 0, 12, 12, 27, 27, 27, 12,
194  12, 32, 32, 32, 40, 40, 40,
195 };
196 const short yycheck[] =
197  { 10,
198  0, 0, 59, 59, 123, 10, 59, 10, 10, 27,
199  10, 10, 10, 10, 10, 10, 10, 27, 27, 6,
200  259, 10, 32, 32, 10, 260, 265, 262, 20, 258,
201  259, 260, 261, 262, 44, 44, 265, 265, 258, 259,
202  27, 51, 262, 5, 260, 265, 262, 65, 40, 258,
203  259, 61, 261, 40, 59, 10, 265, 67, 264, 21,
204  5, 71, 10, 25, 56, 59, 53, 59, 59, 31,
205  59, 33, 10, 59, 66, 10, 21, 10, 65, 264,
206  67, 41, 258, 259, 71, 29, 31, 49, 33, 265,
207  263, 264, 65, 25, 48, 25, -1, -1, -1, -1,
208  -1, -1, -1, -1, 49, -1, -1, -1, -1, -1,
209  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
210  125, -1, 125, -1, -1, -1, -1, 125, 125, 125,
211  -1, 125, -1, -1, -1, -1, 125, -1, -1, 125,
212  -1, -1, -1, -1, -1, 264, 265, -1, -1, -1,
213  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
214  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
215  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
216  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
217  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
218  -1, -1, -1, 260, 261, 262, 262, -1, 261, -1,
219  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
220  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
221  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
222  -1, -1, -1, -1, -1, -1, -1, -1, 259, -1,
223  -1, -1, -1, -1, 265, 260, 261, 262, 260, 264,
224  262, 264, 264, -1, 264, 264, 260, 261, 262, 264,
225  264, 260, 261, 262, 260, 261, 262,
226 };
227 #define YYFINAL 4
228 #ifndef YYDEBUG
229 #define YYDEBUG 0
230 #endif
231 #define YYMAXTOKEN 265
232 #if YYDEBUG
233 const char * const yyname[] =
234  {
235 "end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
236 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"';'",0,0,0,0,0,0,0,0,0,
237 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
238 0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
239 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
240 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
241 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"ERROR",
242 "HIDDEN","IF","ELSE","ELIF","ENDIF","FORMAT","TOKEN","EQUALS",
243 };
244 const char * const yyrule[] =
245  {"$accept : lines",
246 "lines :",
247 "lines : statements",
248 "statements : statement '\\n'",
249 "statements : statements statement '\\n'",
250 "statement :",
251 "statement : hidden_assignment",
252 "statement : condition",
253 "statement : commands",
254 "format : FORMAT",
255 "format : TOKEN",
256 "expanded : format",
257 "optional_assignment :",
258 "optional_assignment : assignment",
259 "assignment : EQUALS",
260 "hidden_assignment : HIDDEN EQUALS",
261 "if_open : IF expanded",
262 "if_else : ELSE",
263 "if_elif : ELIF expanded",
264 "if_close : ENDIF",
265 "condition : if_open '\\n' statements if_close",
266 "condition : if_open '\\n' statements if_else '\\n' statements if_close",
267 "condition : if_open '\\n' statements elif if_close",
268 "condition : if_open '\\n' statements elif if_else '\\n' statements if_close",
269 "elif : if_elif '\\n' statements",
270 "elif : if_elif '\\n' statements elif",
271 "commands : command",
272 "commands : commands ';'",
273 "commands : commands ';' condition1",
274 "commands : commands ';' command",
275 "commands : condition1",
276 "command : assignment",
277 "command : optional_assignment TOKEN",
278 "command : optional_assignment TOKEN arguments",
279 "condition1 : if_open commands if_close",
280 "condition1 : if_open commands if_else commands if_close",
281 "condition1 : if_open commands elif1 if_close",
282 "condition1 : if_open commands elif1 if_else commands if_close",
283 "elif1 : if_elif commands",
284 "elif1 : if_elif commands elif1",
285 "arguments : argument",
286 "arguments : argument arguments",
287 "argument : TOKEN",
288 "argument : EQUALS",
289 "argument : '{' argument_statements",
290 "argument_statements : statement '}'",
291 "argument_statements : statements statement '}'",
292 };
293 #endif
294 #ifdef YYSTACKSIZE
295 #undef YYMAXDEPTH
296 #define YYMAXDEPTH YYSTACKSIZE
297 #else
298 #ifdef YYMAXDEPTH
299 #define YYSTACKSIZE YYMAXDEPTH
300 #else
301 #define YYSTACKSIZE 10000
302 #define YYMAXDEPTH 10000
303 #endif
304 #endif
305 #define YYINITSTACKSIZE 200
306 /* LINTUSED */
310 int yychar;
311 short *yyssp;
315 short *yyss;
316 short *yysslim;
318 unsigned int yystacksize;
319 int yyparse(void);
320 #line 546 "cmd-parse.y"
321 
322 static char *
323 cmd_parse_get_error(const char *file, u_int line, const char *error)
324 {
325  char *s;
326 
327  if (file == NULL)
328  s = xstrdup(error);
329  else
330  xasprintf (&s, "%s:%u: %s", file, line, error);
331  return (s);
332 }
333 
334 static void
336  struct cmd_list *cmdlist)
337 {
338  char *s;
339 
340  if (pi->item != NULL && (pi->flags & CMD_PARSE_VERBOSE)) {
341  s = cmd_list_print(cmdlist, 0);
342  if (pi->file != NULL)
343  cmdq_print(pi->item, "%s:%u: %s", pi->file, line, s);
344  else
345  cmdq_print(pi->item, "%u: %s", line, s);
346  free(s);
347  }
348 }
349 
350 static void
352 {
354  free(cmd);
355 }
356 
357 static struct cmd_parse_commands *
359 {
360  struct cmd_parse_commands *cmds;
361 
362  cmds = xmalloc(sizeof *cmds);
363  TAILQ_INIT (cmds);
364  return (cmds);
365 }
366 
367 static void
368 cmd_parse_free_commands(struct cmd_parse_commands *cmds)
369 {
370  struct cmd_parse_command *cmd, *cmd1;
371 
372  TAILQ_FOREACH_SAFE(cmd, cmds, entry, cmd1) {
373  TAILQ_REMOVE(cmds, cmd, entry);
375  }
376  free(cmds);
377 }
378 
379 static char *
380 cmd_parse_commands_to_string(struct cmd_parse_commands *cmds)
381 {
382  struct cmd_parse_command *cmd;
383  char *string = NULL, *s, *line;
384 
385  TAILQ_FOREACH(cmd, cmds, entry) {
387  if (string == NULL)
388  s = line;
389  else {
390  xasprintf(&s, "%s ; %s", s, line);
391  free(line);
392  }
393 
394  free(string);
395  string = s;
396  }
397  if (string == NULL)
398  string = xstrdup("");
399  log_debug("%s: %s", __func__, string);
400  return (string);
401 }
402 
403 static struct cmd_parse_commands *
404 cmd_parse_run_parser(char **cause)
405 {
406  struct cmd_parse_state *ps = &parse_state;
407  struct cmd_parse_scope *scope, *scope1;
408  int retval;
409 
410  ps->commands = NULL;
411  TAILQ_INIT(&ps->stack);
412 
413  retval = yyparse();
414  TAILQ_FOREACH_SAFE(scope, &ps->stack, entry, scope1) {
415  TAILQ_REMOVE(&ps->stack, scope, entry);
416  free(scope);
417  }
418  if (retval != 0) {
419  *cause = ps->error;
420  return (NULL);
421  }
422 
423  if (ps->commands == NULL)
424  return (cmd_parse_new_commands());
425  return (ps->commands);
426 }
427 
428 static struct cmd_parse_commands *
429 cmd_parse_do_file(FILE *f, struct cmd_parse_input *pi, char **cause)
430 {
431  struct cmd_parse_state *ps = &parse_state;
432 
433  memset(ps, 0, sizeof *ps);
434  ps->input = pi;
435  ps->f = f;
436  return (cmd_parse_run_parser(cause));
437 }
438 
439 static struct cmd_parse_commands *
440 cmd_parse_do_buffer(const char *buf, size_t len, struct cmd_parse_input *pi,
441  char **cause)
442 {
443  struct cmd_parse_state *ps = &parse_state;
444 
445  memset(ps, 0, sizeof *ps);
446  ps->input = pi;
447  ps->buf = buf;
448  ps->len = len;
449  return (cmd_parse_run_parser(cause));
450 }
451 
452 static struct cmd_parse_result *
453 cmd_parse_build_commands(struct cmd_parse_commands *cmds,
454  struct cmd_parse_input *pi)
455 {
456  static struct cmd_parse_result pr;
457  struct cmd_parse_commands *cmds2;
458  struct cmd_parse_command *cmd, *cmd2, *next, *next2, *after;
459  u_int line = UINT_MAX;
460  int i;
461  struct cmd_list *cmdlist = NULL, *result;
462  struct cmd *add;
463  char *name, *alias, *cause, *s;
464 
465  /* Check for an empty list. */
466  if (TAILQ_EMPTY(cmds)) {
468  pr.status = CMD_PARSE_EMPTY;
469  return (&pr);
470  }
471 
472  /*
473  * Walk the commands and expand any aliases. Each alias is parsed
474  * individually to a new command list, any trailing arguments appended
475  * to the last command, and all commands inserted into the original
476  * command list.
477  */
478  TAILQ_FOREACH_SAFE(cmd, cmds, entry, next) {
479  name = cmd->argv[0];
480 
482  if (alias == NULL)
483  continue;
484 
485  line = cmd->line;
486  log_debug("%s: %u %s = %s", __func__, line, name, alias);
487 
488  pi->line = line;
489  cmds2 = cmd_parse_do_buffer(alias, strlen(alias), pi, &cause);
490  free(alias);
491  if (cmds2 == NULL) {
492  pr.status = CMD_PARSE_ERROR;
493  pr.error = cause;
494  goto out;
495  }
496 
497  cmd2 = TAILQ_LAST(cmds2, cmd_parse_commands);
498  if (cmd2 == NULL) {
499  TAILQ_REMOVE(cmds, cmd, entry);
501  continue;
502  }
503  for (i = 1; i < cmd->argc; i++)
504  cmd_append_argv(&cmd2->argc, &cmd2->argv, cmd->argv[i]);
505 
506  after = cmd;
507  TAILQ_FOREACH_SAFE(cmd2, cmds2, entry, next2) {
508  cmd2->line = line;
509  TAILQ_REMOVE(cmds2, cmd2, entry);
510  TAILQ_INSERT_AFTER(cmds, after, cmd2, entry);
511  after = cmd2;
512  }
514 
515  TAILQ_REMOVE(cmds, cmd, entry);
517  }
518 
519  /*
520  * Parse each command into a command list. Create a new command list
521  * for each line (unless the flag is set) so they get a new group (so
522  * the queue knows which ones to remove if a command fails when
523  * executed).
524  */
525  result = cmd_list_new();
526  TAILQ_FOREACH(cmd, cmds, entry) {
527  name = cmd->argv[0];
528  log_debug("%s: %u %s", __func__, cmd->line, name);
529  cmd_log_argv(cmd->argc, cmd->argv, __func__);
530 
531  if (cmdlist == NULL ||
532  ((~pi->flags & CMD_PARSE_ONEGROUP) && cmd->line != line)) {
533  if (cmdlist != NULL) {
534  cmd_parse_print_commands(pi, line, cmdlist);
535  cmd_list_move(result, cmdlist);
536  cmd_list_free(cmdlist);
537  }
538  cmdlist = cmd_list_new();
539  }
540  line = cmd->line;
541 
542  add = cmd_parse(cmd->argc, cmd->argv, pi->file, line, &cause);
543  if (add == NULL) {
544  cmd_list_free(result);
545  pr.status = CMD_PARSE_ERROR;
546  pr.error = cmd_parse_get_error(pi->file, line, cause);
547  free(cause);
548  cmd_list_free(cmdlist);
549  goto out;
550  }
551  cmd_list_append(cmdlist, add);
552  }
553  if (cmdlist != NULL) {
554  cmd_parse_print_commands(pi, line, cmdlist);
555  cmd_list_move(result, cmdlist);
556  cmd_list_free(cmdlist);
557  }
558 
559  s = cmd_list_print(result, 0);
560  log_debug("%s: %s", __func__, s);
561  free(s);
562 
564  pr.cmdlist = result;
565 
566 out:
568 
569  return (&pr);
570 }
571 
572 struct cmd_parse_result *
574 {
575  static struct cmd_parse_result pr;
576  struct cmd_parse_input input;
577  struct cmd_parse_commands *cmds;
578  char *cause;
579 
580  if (pi == NULL) {
581  memset(&input, 0, sizeof input);
582  pi = &input;
583  }
584  memset(&pr, 0, sizeof pr);
585 
586  cmds = cmd_parse_do_file(f, pi, &cause);
587  if (cmds == NULL) {
588  pr.status = CMD_PARSE_ERROR;
589  pr.error = cause;
590  return (&pr);
591  }
592  return (cmd_parse_build_commands(cmds, pi));
593 }
594 
595 struct cmd_parse_result *
596 cmd_parse_from_string(const char *s, struct cmd_parse_input *pi)
597 {
598  struct cmd_parse_input input;
599 
600  if (pi == NULL) {
601  memset(&input, 0, sizeof input);
602  pi = &input;
603  }
604 
605  /*
606  * When parsing a string, put commands in one group even if there are
607  * multiple lines. This means { a \n b } is identical to "a ; b" when
608  * given as an argument to another command.
609  */
610  pi->flags |= CMD_PARSE_ONEGROUP;
611  return (cmd_parse_from_buffer(s, strlen(s), pi));
612 }
613 
614 enum cmd_parse_status
615 cmd_parse_and_insert(const char *s, struct cmd_parse_input *pi,
616  struct cmdq_item *after, struct cmdq_state *state, char **error)
617 {
618  struct cmd_parse_result *pr;
619  struct cmdq_item *item;
620 
621  pr = cmd_parse_from_string(s, pi);
622  switch (pr->status) {
623  case CMD_PARSE_EMPTY:
624  break;
625  case CMD_PARSE_ERROR:
626  if (error != NULL)
627  *error = pr->error;
628  else
629  free(pr->error);
630  break;
631  case CMD_PARSE_SUCCESS:
632  item = cmdq_get_command(pr->cmdlist, state);
633  cmdq_insert_after(after, item);
634  cmd_list_free(pr->cmdlist);
635  break;
636  }
637  return (pr->status);
638 }
639 
640 enum cmd_parse_status
641 cmd_parse_and_append(const char *s, struct cmd_parse_input *pi,
642  struct client *c, struct cmdq_state *state, char **error)
643 {
644  struct cmd_parse_result *pr;
645  struct cmdq_item *item;
646 
647  pr = cmd_parse_from_string(s, pi);
648  switch (pr->status) {
649  case CMD_PARSE_EMPTY:
650  break;
651  case CMD_PARSE_ERROR:
652  if (error != NULL)
653  *error = pr->error;
654  else
655  free(pr->error);
656  break;
657  case CMD_PARSE_SUCCESS:
658  item = cmdq_get_command(pr->cmdlist, state);
659  cmdq_append(c, item);
660  cmd_list_free(pr->cmdlist);
661  break;
662  }
663  return (pr->status);
664 }
665 
666 struct cmd_parse_result *
667 cmd_parse_from_buffer(const void *buf, size_t len, struct cmd_parse_input *pi)
668 {
669  static struct cmd_parse_result pr;
670  struct cmd_parse_input input;
671  struct cmd_parse_commands *cmds;
672  char *cause;
673 
674  if (pi == NULL) {
675  memset(&input, 0, sizeof input);
676  pi = &input;
677  }
678  memset(&pr, 0, sizeof pr);
679 
680  if (len == 0) {
681  pr.status = CMD_PARSE_EMPTY;
682  pr.cmdlist = NULL;
683  pr.error = NULL;
684  return (&pr);
685  }
686 
687  cmds = cmd_parse_do_buffer(buf, len, pi, &cause);
688  if (cmds == NULL) {
689  pr.status = CMD_PARSE_ERROR;
690  pr.error = cause;
691  return (&pr);
692  }
693  return (cmd_parse_build_commands(cmds, pi));
694 }
695 
696 struct cmd_parse_result *
697 cmd_parse_from_arguments(int argc, char **argv, struct cmd_parse_input *pi)
698 {
699  struct cmd_parse_input input;
700  struct cmd_parse_commands *cmds;
701  struct cmd_parse_command *cmd;
702  char **copy, **new_argv;
703  size_t size;
704  int i, last, new_argc;
705 
706  /*
707  * The commands are already split up into arguments, so just separate
708  * into a set of commands by ';'.
709  */
710 
711  if (pi == NULL) {
712  memset(&input, 0, sizeof input);
713  pi = &input;
714  }
715  cmd_log_argv(argc, argv, "%s", __func__);
716 
717  cmds = cmd_parse_new_commands();
718  copy = cmd_copy_argv(argc, argv);
719 
720  last = 0;
721  for (i = 0; i < argc; i++) {
722  size = strlen(copy[i]);
723  if (size == 0 || copy[i][size - 1] != ';')
724  continue;
725  copy[i][--size] = '\0';
726  if (size > 0 && copy[i][size - 1] == '\\') {
727  copy[i][size - 1] = ';';
728  continue;
729  }
730 
731  new_argc = i - last;
732  new_argv = copy + last;
733  if (size != 0)
734  new_argc++;
735 
736  if (new_argc != 0) {
737  cmd_log_argv(new_argc, new_argv, "%s: at %u", __func__,
738  i);
739 
740  cmd = xcalloc(1, sizeof *cmd);
741  cmd->line = pi->line;
742 
743  cmd->argc = new_argc;
744  cmd->argv = cmd_copy_argv(new_argc, new_argv);
745 
746  TAILQ_INSERT_TAIL(cmds, cmd, entry);
747  }
748 
749  last = i + 1;
750  }
751  if (last != argc) {
752  new_argv = copy + last;
753  new_argc = argc - last;
754 
755  if (new_argc != 0) {
756  cmd_log_argv(new_argc, new_argv, "%s: at %u", __func__,
757  last);
758 
759  cmd = xcalloc(1, sizeof *cmd);
760  cmd->line = pi->line;
761 
762  cmd->argc = new_argc;
763  cmd->argv = cmd_copy_argv(new_argc, new_argv);
764 
765  TAILQ_INSERT_TAIL(cmds, cmd, entry);
766  }
767  }
768 
769  cmd_free_argv(argc, copy);
770  return (cmd_parse_build_commands(cmds, pi));
771 }
772 
773 static int printflike(1, 2)
774 yyerror(const char *fmt, ...)
775 {
776  struct cmd_parse_state *ps = &parse_state;
777  struct cmd_parse_input *pi = ps->input;
778  va_list ap;
779  char *error;
780 
781  if (ps->error != NULL)
782  return (0);
783 
784  va_start(ap, fmt);
785  xvasprintf(&error, fmt, ap);
786  va_end(ap);
787 
788  ps->error = cmd_parse_get_error(pi->file, pi->line, error);
789  free(error);
790  return (0);
791 }
792 
793 static int
794 yylex_is_var(char ch, int first)
795 {
796  if (ch == '=')
797  return (0);
798  if (first && isdigit((u_char)ch))
799  return (0);
800  return (isalnum((u_char)ch) || ch == '_');
801 }
802 
803 static void
804 yylex_append(char **buf, size_t *len, const char *add, size_t addlen)
805 {
806  if (addlen > SIZE_MAX - 1 || *len > SIZE_MAX - 1 - addlen)
807  fatalx("buffer is too big");
808  *buf = xrealloc(*buf, (*len) + 1 + addlen);
809  memcpy((*buf) + *len, add, addlen);
810  (*len) += addlen;
811 }
812 
813 static void
814 yylex_append1(char **buf, size_t *len, char add)
815 {
816  yylex_append(buf, len, &add, 1);
817 }
818 
819 static int
821 {
822  struct cmd_parse_state *ps = &parse_state;
823  int ch;
824 
825  if (ps->f != NULL)
826  ch = getc(ps->f);
827  else {
828  if (ps->off == ps->len)
829  ch = EOF;
830  else
831  ch = ps->buf[ps->off++];
832  }
833  return (ch);
834 }
835 
836 static void
838 {
839  struct cmd_parse_state *ps = &parse_state;
840 
841  if (ps->f != NULL)
842  ungetc(ch, ps->f);
843  else if (ps->off > 0 && ch != EOF)
844  ps->off--;
845 }
846 
847 static int
849 {
850  struct cmd_parse_state *ps = &parse_state;
851  int ch;
852 
853  if (ps->escapes != 0) {
854  ps->escapes--;
855  return ('\\');
856  }
857  for (;;) {
858  ch = yylex_getc1();
859  if (ch == '\\') {
860  ps->escapes++;
861  continue;
862  }
863  if (ch == '\n' && (ps->escapes % 2) == 1) {
864  ps->input->line++;
865  ps->escapes--;
866  continue;
867  }
868 
869  if (ps->escapes != 0) {
870  yylex_ungetc(ch);
871  ps->escapes--;
872  return ('\\');
873  }
874  return (ch);
875  }
876 }
877 
878 static char *
880 {
881  char *buf;
882  size_t len;
883 
884  len = 0;
885  buf = xmalloc(1);
886 
887  do
888  yylex_append1(&buf, &len, ch);
889  while ((ch = yylex_getc()) != EOF && strchr(" \t\n", ch) == NULL);
890  yylex_ungetc(ch);
891 
892  buf[len] = '\0';
893  log_debug("%s: %s", __func__, buf);
894  return (buf);
895 }
896 
897 static int
898 yylex(void)
899 {
900  struct cmd_parse_state *ps = &parse_state;
901  char *token, *cp;
902  int ch, next, condition;
903 
904  if (ps->eol)
905  ps->input->line++;
906  ps->eol = 0;
907 
908  condition = ps->condition;
909  ps->condition = 0;
910 
911  for (;;) {
912  ch = yylex_getc();
913 
914  if (ch == EOF) {
915  /*
916  * Ensure every file or string is terminated by a
917  * newline. This keeps the parser simpler and avoids
918  * having to add a newline to each string.
919  */
920  if (ps->eof)
921  break;
922  ps->eof = 1;
923  return ('\n');
924  }
925 
926  if (ch == ' ' || ch == '\t') {
927  /*
928  * Ignore whitespace.
929  */
930  continue;
931  }
932 
933  if (ch == '\n') {
934  /*
935  * End of line. Update the line number.
936  */
937  ps->eol = 1;
938  return ('\n');
939  }
940 
941  if (ch == ';' || ch == '{' || ch == '}') {
942  /*
943  * A semicolon or { or } is itself.
944  */
945  return (ch);
946  }
947 
948  if (ch == '#') {
949  /*
950  * #{ after a condition opens a format; anything else
951  * is a comment, ignore up to the end of the line.
952  */
953  next = yylex_getc();
954  if (condition && next == '{') {
956  if (yylval.token == NULL)
957  return (ERROR);
958  return (FORMAT);
959  }
960  while (next != '\n' && next != EOF)
961  next = yylex_getc();
962  if (next == '\n') {
963  ps->input->line++;
964  return ('\n');
965  }
966  continue;
967  }
968 
969  if (ch == '%') {
970  /*
971  * % is a condition unless it is all % or all numbers,
972  * then it is a token.
973  */
974  yylval.token = yylex_get_word('%');
975  for (cp = yylval.token; *cp != '\0'; cp++) {
976  if (*cp != '%' && !isdigit((u_char)*cp))
977  break;
978  }
979  if (*cp == '\0')
980  return (TOKEN);
981  ps->condition = 1;
982  if (strcmp(yylval.token, "%hidden") == 0) {
983  free(yylval.token);
984  return (HIDDEN);
985  }
986  if (strcmp(yylval.token, "%if") == 0) {
987  free(yylval.token);
988  return (IF);
989  }
990  if (strcmp(yylval.token, "%else") == 0) {
991  free(yylval.token);
992  return (ELSE);
993  }
994  if (strcmp(yylval.token, "%elif") == 0) {
995  free(yylval.token);
996  return (ELIF);
997  }
998  if (strcmp(yylval.token, "%endif") == 0) {
999  free(yylval.token);
1000  return (ENDIF);
1001  }
1002  free(yylval.token);
1003  return (ERROR);
1004  }
1005 
1006  /*
1007  * Otherwise this is a token.
1008  */
1009  token = yylex_token(ch);
1010  if (token == NULL)
1011  return (ERROR);
1012  yylval.token = token;
1013 
1014  if (strchr(token, '=') != NULL && yylex_is_var(*token, 1)) {
1015  for (cp = token + 1; *cp != '='; cp++) {
1016  if (!yylex_is_var(*cp, 0))
1017  break;
1018  }
1019  if (*cp == '=')
1020  return (EQUALS);
1021  }
1022  return (TOKEN);
1023  }
1024  return (0);
1025 }
1026 
1027 static char *
1029 {
1030  char *buf;
1031  size_t len;
1032  int ch, brackets = 1;
1033 
1034  len = 0;
1035  buf = xmalloc(1);
1036 
1037  yylex_append(&buf, &len, "#{", 2);
1038  for (;;) {
1039  if ((ch = yylex_getc()) == EOF || ch == '\n')
1040  goto error;
1041  if (ch == '#') {
1042  if ((ch = yylex_getc()) == EOF || ch == '\n')
1043  goto error;
1044  if (ch == '{')
1045  brackets++;
1046  yylex_append1(&buf, &len, '#');
1047  } else if (ch == '}') {
1048  if (brackets != 0 && --brackets == 0) {
1049  yylex_append1(&buf, &len, ch);
1050  break;
1051  }
1052  }
1053  yylex_append1(&buf, &len, ch);
1054  }
1055  if (brackets != 0)
1056  goto error;
1057 
1058  buf[len] = '\0';
1059  log_debug("%s: %s", __func__, buf);
1060  return (buf);
1061 
1062 error:
1063  free(buf);
1064  return (NULL);
1065 }
1066 
1067 static int
1068 yylex_token_escape(char **buf, size_t *len)
1069 {
1070  int ch, type, o2, o3, mlen;
1071  u_int size, i, tmp;
1072  char s[9], m[MB_LEN_MAX];
1073 
1074  ch = yylex_getc();
1075 
1076  if (ch >= '4' && ch <= '7') {
1077  yyerror("invalid octal escape");
1078  return (0);
1079  }
1080  if (ch >= '0' && ch <= '3') {
1081  o2 = yylex_getc();
1082  if (o2 >= '0' && o2 <= '7') {
1083  o3 = yylex_getc();
1084  if (o3 >= '0' && o3 <= '7') {
1085  ch = 64 * (ch - '0') +
1086  8 * (o2 - '0') +
1087  (o3 - '0');
1088  yylex_append1(buf, len, ch);
1089  return (1);
1090  }
1091  }
1092  yyerror("invalid octal escape");
1093  return (0);
1094  }
1095 
1096  switch (ch) {
1097  case EOF:
1098  return (0);
1099  case 'a':
1100  ch = '\a';
1101  break;
1102  case 'b':
1103  ch = '\b';
1104  break;
1105  case 'e':
1106  ch = '\033';
1107  break;
1108  case 'f':
1109  ch = '\f';
1110  break;
1111  case 's':
1112  ch = ' ';
1113  break;
1114  case 'v':
1115  ch = '\v';
1116  break;
1117  case 'r':
1118  ch = '\r';
1119  break;
1120  case 'n':
1121  ch = '\n';
1122  break;
1123  case 't':
1124  ch = '\t';
1125  break;
1126  case 'u':
1127  type = 'u';
1128  size = 4;
1129  goto unicode;
1130  case 'U':
1131  type = 'U';
1132  size = 8;
1133  goto unicode;
1134  }
1135 
1136  yylex_append1(buf, len, ch);
1137  return (1);
1138 
1139 unicode:
1140  for (i = 0; i < size; i++) {
1141  ch = yylex_getc();
1142  if (ch == EOF || ch == '\n')
1143  return (0);
1144  if (!isxdigit((u_char)ch)) {
1145  yyerror("invalid \\%c argument", type);
1146  return (0);
1147  }
1148  s[i] = ch;
1149  }
1150  s[i] = '\0';
1151 
1152  if ((size == 4 && sscanf(s, "%4x", &tmp) != 1) ||
1153  (size == 8 && sscanf(s, "%8x", &tmp) != 1)) {
1154  yyerror("invalid \\%c argument", type);
1155  return (0);
1156  }
1157  mlen = wctomb(m, tmp);
1158  if (mlen <= 0 || mlen > (int)sizeof m) {
1159  yyerror("invalid \\%c argument", type);
1160  return (0);
1161  }
1162  yylex_append(buf, len, m, mlen);
1163  return (1);
1164 }
1165 
1166 static int
1167 yylex_token_variable(char **buf, size_t *len)
1168 {
1169  struct environ_entry *envent;
1170  int ch, brackets = 0;
1171  char name[1024];
1172  size_t namelen = 0;
1173  const char *value;
1174 
1175  ch = yylex_getc();
1176  if (ch == EOF)
1177  return (0);
1178  if (ch == '{')
1179  brackets = 1;
1180  else {
1181  if (!yylex_is_var(ch, 1)) {
1182  yylex_append1(buf, len, '$');
1183  yylex_ungetc(ch);
1184  return (1);
1185  }
1186  name[namelen++] = ch;
1187  }
1188 
1189  for (;;) {
1190  ch = yylex_getc();
1191  if (brackets && ch == '}')
1192  break;
1193  if (ch == EOF || !yylex_is_var(ch, 0)) {
1194  if (!brackets) {
1195  yylex_ungetc(ch);
1196  break;
1197  }
1198  yyerror("invalid environment variable");
1199  return (0);
1200  }
1201  if (namelen == (sizeof name) - 2) {
1202  yyerror("environment variable is too long");
1203  return (0);
1204  }
1205  name[namelen++] = ch;
1206  }
1207  name[namelen] = '\0';
1208 
1209  envent = environ_find(global_environ, name);
1210  if (envent != NULL && envent->value != NULL) {
1211  value = envent->value;
1212  log_debug("%s: %s -> %s", __func__, name, value);
1213  yylex_append(buf, len, value, strlen(value));
1214  }
1215  return (1);
1216 }
1217 
1218 static int
1219 yylex_token_tilde(char **buf, size_t *len)
1220 {
1221  struct environ_entry *envent;
1222  int ch;
1223  char name[1024];
1224  size_t namelen = 0;
1225  struct passwd *pw;
1226  const char *home = NULL;
1227 
1228  for (;;) {
1229  ch = yylex_getc();
1230  if (ch == EOF || strchr("/ \t\n\"'", ch) != NULL) {
1231  yylex_ungetc(ch);
1232  break;
1233  }
1234  if (namelen == (sizeof name) - 2) {
1235  yyerror("user name is too long");
1236  return (0);
1237  }
1238  name[namelen++] = ch;
1239  }
1240  name[namelen] = '\0';
1241 
1242  if (*name == '\0') {
1243  envent = environ_find(global_environ, "HOME");
1244  if (envent != NULL && *envent->value != '\0')
1245  home = envent->value;
1246  else if ((pw = getpwuid(getuid())) != NULL)
1247  home = pw->pw_dir;
1248  } else {
1249  if ((pw = getpwnam(name)) != NULL)
1250  home = pw->pw_dir;
1251  }
1252  if (home == NULL)
1253  return (0);
1254 
1255  log_debug("%s: ~%s -> %s", __func__, name, home);
1256  yylex_append(buf, len, home, strlen(home));
1257  return (1);
1258 }
1259 
1260 static char *
1262 {
1263  char *buf;
1264  size_t len;
1265  enum { START,
1266  NONE,
1267  DOUBLE_QUOTES,
1268  SINGLE_QUOTES } state = NONE, last = START;
1269 
1270  len = 0;
1271  buf = xmalloc(1);
1272 
1273  for (;;) {
1274  /* EOF or \n are always the end of the token. */
1275  if (ch == EOF || (state == NONE && ch == '\n'))
1276  break;
1277 
1278  /* Whitespace or ; or } ends a token unless inside quotes. */
1279  if ((ch == ' ' || ch == '\t' || ch == ';' || ch == '}') &&
1280  state == NONE)
1281  break;
1282 
1283  /*
1284  * Spaces and comments inside quotes after \n are removed but
1285  * the \n is left.
1286  */
1287  if (ch == '\n' && state != NONE) {
1288  yylex_append1(&buf, &len, '\n');
1289  while ((ch = yylex_getc()) == ' ' || ch == '\t')
1290  /* nothing */;
1291  if (ch != '#')
1292  continue;
1293  ch = yylex_getc();
1294  if (strchr(",#{}:", ch) != NULL) {
1295  yylex_ungetc(ch);
1296  ch = '#';
1297  } else {
1298  while ((ch = yylex_getc()) != '\n' && ch != EOF)
1299  /* nothing */;
1300  }
1301  continue;
1302  }
1303 
1304  /* \ ~ and $ are expanded except in single quotes. */
1305  if (ch == '\\' && state != SINGLE_QUOTES) {
1306  if (!yylex_token_escape(&buf, &len))
1307  goto error;
1308  goto skip;
1309  }
1310  if (ch == '~' && last != state && state != SINGLE_QUOTES) {
1311  if (!yylex_token_tilde(&buf, &len))
1312  goto error;
1313  goto skip;
1314  }
1315  if (ch == '$' && state != SINGLE_QUOTES) {
1316  if (!yylex_token_variable(&buf, &len))
1317  goto error;
1318  goto skip;
1319  }
1320  if (ch == '}' && state == NONE)
1321  goto error; /* unmatched (matched ones were handled) */
1322 
1323  /* ' and " starts or end quotes (and is consumed). */
1324  if (ch == '\'') {
1325  if (state == NONE) {
1326  state = SINGLE_QUOTES;
1327  goto next;
1328  }
1329  if (state == SINGLE_QUOTES) {
1330  state = NONE;
1331  goto next;
1332  }
1333  }
1334  if (ch == '"') {
1335  if (state == NONE) {
1336  state = DOUBLE_QUOTES;
1337  goto next;
1338  }
1339  if (state == DOUBLE_QUOTES) {
1340  state = NONE;
1341  goto next;
1342  }
1343  }
1344 
1345  /* Otherwise add the character to the buffer. */
1346  yylex_append1(&buf, &len, ch);
1347 
1348  skip:
1349  last = state;
1350 
1351  next:
1352  ch = yylex_getc();
1353  }
1354  yylex_ungetc(ch);
1355 
1356  buf[len] = '\0';
1357  log_debug("%s: %s", __func__, buf);
1358  return (buf);
1359 
1360 error:
1361  free(buf);
1362  return (NULL);
1363 }
1364 #line 1357 "cmd-parse.c"
1365 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
1366 static int yygrowstack(void)
1367 {
1368  unsigned int newsize;
1369  long sslen;
1370  short *newss;
1371  YYSTYPE *newvs;
1372 
1373  if ((newsize = yystacksize) == 0)
1374  newsize = YYINITSTACKSIZE;
1375  else if (newsize >= YYMAXDEPTH)
1376  return -1;
1377  else if ((newsize *= 2) > YYMAXDEPTH)
1378  newsize = YYMAXDEPTH;
1379  sslen = yyssp - yyss;
1380 #ifdef SIZE_MAX
1381 #define YY_SIZE_MAX SIZE_MAX
1382 #else
1383 #define YY_SIZE_MAX 0xffffffffU
1384 #endif
1385  if (newsize && YY_SIZE_MAX / newsize < sizeof *newss)
1386  goto bail;
1387  newss = (short *)realloc(yyss, newsize * sizeof *newss);
1388  if (newss == NULL)
1389  goto bail;
1390  yyss = newss;
1391  yyssp = newss + sslen;
1392  if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs)
1393  goto bail;
1394  newvs = (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs);
1395  if (newvs == NULL)
1396  goto bail;
1397  yyvs = newvs;
1398  yyvsp = newvs + sslen;
1399  yystacksize = newsize;
1400  yysslim = yyss + newsize - 1;
1401  return 0;
1402 bail:
1403  if (yyss)
1404  free(yyss);
1405  if (yyvs)
1406  free(yyvs);
1407  yyss = yyssp = NULL;
1408  yyvs = yyvsp = NULL;
1409  yystacksize = 0;
1410  return -1;
1411 }
1412 
1413 #define YYABORT goto yyabort
1414 #define YYREJECT goto yyabort
1415 #define YYACCEPT goto yyaccept
1416 #define YYERROR goto yyerrlab
1417 int
1418 yyparse(void)
1419 {
1420  int yym, yyn, yystate;
1421 #if YYDEBUG
1422  const char *yys;
1423 
1424  if ((yys = getenv("YYDEBUG")))
1425  {
1426  yyn = *yys;
1427  if (yyn >= '0' && yyn <= '9')
1428  yydebug = yyn - '0';
1429  }
1430 #endif /* YYDEBUG */
1431 
1432  yynerrs = 0;
1433  yyerrflag = 0;
1434  yychar = (-1);
1435 
1436  if (yyss == NULL && yygrowstack()) goto yyoverflow;
1437  yyssp = yyss;
1438  yyvsp = yyvs;
1439  *yyssp = yystate = 0;
1440 
1441 yyloop:
1442  if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
1443  if (yychar < 0)
1444  {
1445  if ((yychar = yylex()) < 0) yychar = 0;
1446 #if YYDEBUG
1447  if (yydebug)
1448  {
1449  yys = 0;
1450  if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1451  if (!yys) yys = "illegal-symbol";
1452  printf("%sdebug: state %d, reading %d (%s)\n",
1453  YYPREFIX, yystate, yychar, yys);
1454  }
1455 #endif
1456  }
1457  if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
1458  yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1459  {
1460 #if YYDEBUG
1461  if (yydebug)
1462  printf("%sdebug: state %d, shifting to state %d\n",
1463  YYPREFIX, yystate, yytable[yyn]);
1464 #endif
1465  if (yyssp >= yysslim && yygrowstack())
1466  {
1467  goto yyoverflow;
1468  }
1469  *++yyssp = yystate = yytable[yyn];
1470  *++yyvsp = yylval;
1471  yychar = (-1);
1472  if (yyerrflag > 0) --yyerrflag;
1473  goto yyloop;
1474  }
1475  if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
1476  yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1477  {
1478  yyn = yytable[yyn];
1479  goto yyreduce;
1480  }
1481  if (yyerrflag) goto yyinrecovery;
1482 #if defined(__GNUC__)
1483  goto yynewerror;
1484 #endif
1485 yynewerror:
1486  yyerror("syntax error");
1487 #if defined(__GNUC__)
1488  goto yyerrlab;
1489 #endif
1490 yyerrlab:
1491  ++yynerrs;
1492 yyinrecovery:
1493  if (yyerrflag < 3)
1494  {
1495  yyerrflag = 3;
1496  for (;;)
1497  {
1498  if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
1499  yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
1500  {
1501 #if YYDEBUG
1502  if (yydebug)
1503  printf("%sdebug: state %d, error recovery shifting\
1504  to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
1505 #endif
1506  if (yyssp >= yysslim && yygrowstack())
1507  {
1508  goto yyoverflow;
1509  }
1510  *++yyssp = yystate = yytable[yyn];
1511  *++yyvsp = yylval;
1512  goto yyloop;
1513  }
1514  else
1515  {
1516 #if YYDEBUG
1517  if (yydebug)
1518  printf("%sdebug: error recovery discarding state %d\n",
1519  YYPREFIX, *yyssp);
1520 #endif
1521  if (yyssp <= yyss) goto yyabort;
1522  --yyssp;
1523  --yyvsp;
1524  }
1525  }
1526  }
1527  else
1528  {
1529  if (yychar == 0) goto yyabort;
1530 #if YYDEBUG
1531  if (yydebug)
1532  {
1533  yys = 0;
1534  if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1535  if (!yys) yys = "illegal-symbol";
1536  printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1537  YYPREFIX, yystate, yychar, yys);
1538  }
1539 #endif
1540  yychar = (-1);
1541  goto yyloop;
1542  }
1543 yyreduce:
1544 #if YYDEBUG
1545  if (yydebug)
1546  printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1547  YYPREFIX, yystate, yyn, yyrule[yyn]);
1548 #endif
1549  yym = yylen[yyn];
1550  if (yym)
1551  yyval = yyvsp[1-yym];
1552  else
1553  memset(&yyval, 0, sizeof yyval);
1554  switch (yyn)
1555  {
1556 case 2:
1557 #line 122 "cmd-parse.y"
1558 {
1559  struct cmd_parse_state *ps = &parse_state;
1560 
1561  ps->commands = yyvsp[0].commands;
1562  }
1563 break;
1564 case 3:
1565 #line 129 "cmd-parse.y"
1566 {
1567  yyval.commands = yyvsp[-1].commands;
1568  }
1569 break;
1570 case 4:
1571 #line 133 "cmd-parse.y"
1572 {
1573  yyval.commands = yyvsp[-2].commands;
1574  TAILQ_CONCAT(yyval.commands, yyvsp[-1].commands, entry);
1575  free(yyvsp[-1].commands);
1576  }
1577 break;
1578 case 5:
1579 #line 140 "cmd-parse.y"
1580 {
1581  yyval.commands = xmalloc (sizeof *yyval.commands);
1582  TAILQ_INIT(yyval.commands);
1583  }
1584 break;
1585 case 6:
1586 #line 145 "cmd-parse.y"
1587 {
1588  yyval.commands = xmalloc (sizeof *yyval.commands);
1589  TAILQ_INIT(yyval.commands);
1590  }
1591 break;
1592 case 7:
1593 #line 150 "cmd-parse.y"
1594 {
1595  struct cmd_parse_state *ps = &parse_state;
1596 
1597  if (ps->scope == NULL || ps->scope->flag)
1599  else {
1602  }
1603  }
1604 break;
1605 case 8:
1606 #line 161 "cmd-parse.y"
1607 {
1608  struct cmd_parse_state *ps = &parse_state;
1609 
1610  if (ps->scope == NULL || ps->scope->flag)
1612  else {
1615  }
1616  }
1617 break;
1618 case 9:
1619 #line 173 "cmd-parse.y"
1620 {
1621  yyval.token = yyvsp[0].token;
1622  }
1623 break;
1624 case 10:
1625 #line 177 "cmd-parse.y"
1626 {
1627  yyval.token = yyvsp[0].token;
1628  }
1629 break;
1630 case 11:
1631 #line 182 "cmd-parse.y"
1632 {
1633  struct cmd_parse_state *ps = &parse_state;
1634  struct cmd_parse_input *pi = ps->input;
1635  struct format_tree *ft;
1636  struct client *c = pi->c;
1637  struct cmd_find_state *fsp;
1638  struct cmd_find_state fs;
1639  int flags = FORMAT_NOJOBS;
1640 
1641  if (cmd_find_valid_state(&pi->fs))
1642  fsp = &pi->fs;
1643  else {
1644  cmd_find_from_client(&fs, c, 0);
1645  fsp = &fs;
1646  }
1647  ft = format_create(NULL, pi->item, FORMAT_NONE, flags);
1648  format_defaults(ft, c, fsp->s, fsp->wl, fsp->wp);
1649 
1650  yyval.token = format_expand(ft, yyvsp[0].token);
1651  format_free(ft);
1652  free(yyvsp[0].token);
1653  }
1654 break;
1655 case 14:
1656 #line 209 "cmd-parse.y"
1657 {
1658  struct cmd_parse_state *ps = &parse_state;
1659  int flags = ps->input->flags;
1660 
1661  if ((~flags & CMD_PARSE_PARSEONLY) &&
1662  (ps->scope == NULL || ps->scope->flag))
1663  environ_put(global_environ, yyvsp[0].token, 0);
1664  free(yyvsp[0].token);
1665  }
1666 break;
1667 case 15:
1668 #line 220 "cmd-parse.y"
1669 {
1670  struct cmd_parse_state *ps = &parse_state;
1671  int flags = ps->input->flags;
1672 
1673  if ((~flags & CMD_PARSE_PARSEONLY) &&
1674  (ps->scope == NULL || ps->scope->flag))
1676  free(yyvsp[0].token);
1677  }
1678 break;
1679 case 16:
1680 #line 231 "cmd-parse.y"
1681 {
1682  struct cmd_parse_state *ps = &parse_state;
1683  struct cmd_parse_scope *scope;
1684 
1685  scope = xmalloc(sizeof *scope);
1686  yyval.flag = scope->flag = format_true(yyvsp[0].token);
1687  free(yyvsp[0].token);
1688 
1689  if (ps->scope != NULL)
1690  TAILQ_INSERT_HEAD(&ps->stack, ps->scope, entry);
1691  ps->scope = scope;
1692  }
1693 break;
1694 case 17:
1695 #line 245 "cmd-parse.y"
1696 {
1697  struct cmd_parse_state *ps = &parse_state;
1698  struct cmd_parse_scope *scope;
1699 
1700  scope = xmalloc(sizeof *scope);
1701  scope->flag = !ps->scope->flag;
1702 
1703  free(ps->scope);
1704  ps->scope = scope;
1705  }
1706 break;
1707 case 18:
1708 #line 257 "cmd-parse.y"
1709 {
1710  struct cmd_parse_state *ps = &parse_state;
1711  struct cmd_parse_scope *scope;
1712 
1713  scope = xmalloc(sizeof *scope);
1714  yyval.flag = scope->flag = format_true(yyvsp[0].token);
1715  free(yyvsp[0].token);
1716 
1717  free(ps->scope);
1718  ps->scope = scope;
1719  }
1720 break;
1721 case 19:
1722 #line 270 "cmd-parse.y"
1723 {
1724  struct cmd_parse_state *ps = &parse_state;
1725 
1726  free(ps->scope);
1727  ps->scope = TAILQ_FIRST(&ps->stack);
1728  if (ps->scope != NULL)
1729  TAILQ_REMOVE(&ps->stack, ps->scope, entry);
1730  }
1731 break;
1732 case 20:
1733 #line 280 "cmd-parse.y"
1734 {
1735  if (yyvsp[-3].flag)
1736  yyval.commands = yyvsp[-1].commands;
1737  else {
1740  }
1741  }
1742 break;
1743 case 21:
1744 #line 289 "cmd-parse.y"
1745 {
1746  if (yyvsp[-6].flag) {
1747  yyval.commands = yyvsp[-4].commands;
1749  } else {
1750  yyval.commands = yyvsp[-1].commands;
1752  }
1753  }
1754 break;
1755 case 22:
1756 #line 299 "cmd-parse.y"
1757 {
1758  if (yyvsp[-4].flag) {
1759  yyval.commands = yyvsp[-2].commands;
1761  } else if (yyvsp[-1].elif.flag) {
1764  } else {
1768  }
1769  }
1770 break;
1771 case 23:
1772 #line 313 "cmd-parse.y"
1773 {
1774  if (yyvsp[-7].flag) {
1775  yyval.commands = yyvsp[-5].commands;
1778  } else if (yyvsp[-4].elif.flag) {
1782  } else {
1783  yyval.commands = yyvsp[-1].commands;
1786  }
1787  }
1788 break;
1789 case 24:
1790 #line 330 "cmd-parse.y"
1791 {
1792  if (yyvsp[-2].flag) {
1793  yyval.elif.flag = 1;
1795  } else {
1796  yyval.elif.flag = 0;
1799  }
1800  }
1801 break;
1802 case 25:
1803 #line 341 "cmd-parse.y"
1804 {
1805  if (yyvsp[-3].flag) {
1806  yyval.elif.flag = 1;
1809  } else if (yyvsp[0].elif.flag) {
1810  yyval.elif.flag = 1;
1813  } else {
1814  yyval.elif.flag = 0;
1818  }
1819  }
1820 break;
1821 case 26:
1822 #line 359 "cmd-parse.y"
1823 {
1824  struct cmd_parse_state *ps = &parse_state;
1825 
1827  if (yyvsp[0].command->argc != 0 &&
1828  (ps->scope == NULL || ps->scope->flag))
1829  TAILQ_INSERT_TAIL(yyval.commands, yyvsp[0].command, entry);
1830  else
1832  }
1833 break;
1834 case 27:
1835 #line 370 "cmd-parse.y"
1836 {
1837  yyval.commands = yyvsp[-1].commands;
1838  }
1839 break;
1840 case 28:
1841 #line 374 "cmd-parse.y"
1842 {
1843  yyval.commands = yyvsp[-2].commands;
1844  TAILQ_CONCAT(yyval.commands, yyvsp[0].commands, entry);
1845  free(yyvsp[0].commands);
1846  }
1847 break;
1848 case 29:
1849 #line 380 "cmd-parse.y"
1850 {
1851  struct cmd_parse_state *ps = &parse_state;
1852 
1853  if (yyvsp[0].command->argc != 0 &&
1854  (ps->scope == NULL || ps->scope->flag)) {
1855  yyval.commands = yyvsp[-2].commands;
1856  TAILQ_INSERT_TAIL(yyval.commands, yyvsp[0].command, entry);
1857  } else {
1861  }
1862  }
1863 break;
1864 case 30:
1865 #line 394 "cmd-parse.y"
1866 {
1868  }
1869 break;
1870 case 31:
1871 #line 399 "cmd-parse.y"
1872 {
1873  struct cmd_parse_state *ps = &parse_state;
1874 
1875  yyval.command = xcalloc(1, sizeof *yyval.command);
1876  yyval.command->line = ps->input->line;
1877  }
1878 break;
1879 case 32:
1880 #line 406 "cmd-parse.y"
1881 {
1882  struct cmd_parse_state *ps = &parse_state;
1883 
1884  yyval.command = xcalloc(1, sizeof *yyval.command);
1885  yyval.command->line = ps->input->line;
1886 
1888 
1889  }
1890 break;
1891 case 33:
1892 #line 416 "cmd-parse.y"
1893 {
1894  struct cmd_parse_state *ps = &parse_state;
1895 
1896  yyval.command = xcalloc(1, sizeof *yyval.command);
1897  yyval.command->line = ps->input->line;
1898 
1902  }
1903 break;
1904 case 34:
1905 #line 428 "cmd-parse.y"
1906 {
1907  if (yyvsp[-2].flag)
1908  yyval.commands = yyvsp[-1].commands;
1909  else {
1912  }
1913  }
1914 break;
1915 case 35:
1916 #line 437 "cmd-parse.y"
1917 {
1918  if (yyvsp[-4].flag) {
1919  yyval.commands = yyvsp[-3].commands;
1921  } else {
1922  yyval.commands = yyvsp[-1].commands;
1924  }
1925  }
1926 break;
1927 case 36:
1928 #line 447 "cmd-parse.y"
1929 {
1930  if (yyvsp[-3].flag) {
1931  yyval.commands = yyvsp[-2].commands;
1933  } else if (yyvsp[-1].elif.flag) {
1936  } else {
1940  }
1941  }
1942 break;
1943 case 37:
1944 #line 461 "cmd-parse.y"
1945 {
1946  if (yyvsp[-5].flag) {
1947  yyval.commands = yyvsp[-4].commands;
1950  } else if (yyvsp[-3].elif.flag) {
1954  } else {
1955  yyval.commands = yyvsp[-1].commands;
1958  }
1959  }
1960 break;
1961 case 38:
1962 #line 478 "cmd-parse.y"
1963 {
1964  if (yyvsp[-1].flag) {
1965  yyval.elif.flag = 1;
1967  } else {
1968  yyval.elif.flag = 0;
1971  }
1972  }
1973 break;
1974 case 39:
1975 #line 489 "cmd-parse.y"
1976 {
1977  if (yyvsp[-2].flag) {
1978  yyval.elif.flag = 1;
1981  } else if (yyvsp[0].elif.flag) {
1982  yyval.elif.flag = 1;
1985  } else {
1986  yyval.elif.flag = 0;
1990  }
1991  }
1992 break;
1993 case 40:
1994 #line 507 "cmd-parse.y"
1995 {
1996  yyval.arguments.argc = 1;
1997  yyval.arguments.argv = xreallocarray(NULL, 1, sizeof *yyval.arguments.argv);
1998 
1999  yyval.arguments.argv[0] = yyvsp[0].token;
2000  }
2001 break;
2002 case 41:
2003 #line 514 "cmd-parse.y"
2004 {
2005  cmd_prepend_argv(&yyvsp[0].arguments.argc, &yyvsp[0].arguments.argv, yyvsp[-1].token);
2006  free(yyvsp[-1].token);
2008  }
2009 break;
2010 case 42:
2011 #line 521 "cmd-parse.y"
2012 {
2013  yyval.token = yyvsp[0].token;
2014  }
2015 break;
2016 case 43:
2017 #line 525 "cmd-parse.y"
2018 {
2019  yyval.token = yyvsp[0].token;
2020  }
2021 break;
2022 case 44:
2023 #line 529 "cmd-parse.y"
2024 {
2027  }
2028 break;
2029 case 45:
2030 #line 535 "cmd-parse.y"
2031 {
2032  yyval.commands = yyvsp[-1].commands;
2033  }
2034 break;
2035 case 46:
2036 #line 539 "cmd-parse.y"
2037 {
2038  yyval.commands = yyvsp[-2].commands;
2039  TAILQ_CONCAT(yyval.commands, yyvsp[-1].commands, entry);
2040  free(yyvsp[-1].commands);
2041  }
2042 break;
2043 #line 2036 "cmd-parse.c"
2044  }
2045  yyssp -= yym;
2046  yystate = *yyssp;
2047  yyvsp -= yym;
2048  yym = yylhs[yyn];
2049  if (yystate == 0 && yym == 0)
2050  {
2051 #if YYDEBUG
2052  if (yydebug)
2053  printf("%sdebug: after reduction, shifting from state 0 to\
2054  state %d\n", YYPREFIX, YYFINAL);
2055 #endif
2056  yystate = YYFINAL;
2057  *++yyssp = YYFINAL;
2058  *++yyvsp = yyval;
2059  if (yychar < 0)
2060  {
2061  if ((yychar = yylex()) < 0) yychar = 0;
2062 #if YYDEBUG
2063  if (yydebug)
2064  {
2065  yys = 0;
2066  if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
2067  if (!yys) yys = "illegal-symbol";
2068  printf("%sdebug: state %d, reading %d (%s)\n",
2069  YYPREFIX, YYFINAL, yychar, yys);
2070  }
2071 #endif
2072  }
2073  if (yychar == 0) goto yyaccept;
2074  goto yyloop;
2075  }
2076  if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
2077  yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
2078  yystate = yytable[yyn];
2079  else
2080  yystate = yydgoto[yym];
2081 #if YYDEBUG
2082  if (yydebug)
2083  printf("%sdebug: after reduction, shifting from state %d \
2084 to state %d\n", YYPREFIX, *yyssp, yystate);
2085 #endif
2086  if (yyssp >= yysslim && yygrowstack())
2087  {
2088  goto yyoverflow;
2089  }
2090  *++yyssp = yystate;
2091  *++yyvsp = yyval;
2092  goto yyloop;
2093 yyoverflow:
2094  yyerror("yacc stack overflow");
2095 yyabort:
2096  if (yyss)
2097  free(yyss);
2098  if (yyvs)
2099  free(yyvs);
2100  yyss = yyssp = NULL;
2101  yyvs = yyvsp = NULL;
2102  yystacksize = 0;
2103  return (1);
2104 yyaccept:
2105  if (yyss)
2106  free(yyss);
2107  if (yyvs)
2108  free(yyvs);
2109  yyss = yyssp = NULL;
2110  yyvs = yyvsp = NULL;
2111  yystacksize = 0;
2112  return (0);
2113 }
int cmd_find_valid_state(struct cmd_find_state *fs)
Definition: cmd-find.c:664
int cmd_find_from_client(struct cmd_find_state *fs, struct client *c, int flags)
Definition: cmd-find.c:859
#define YYINITSTACKSIZE
Definition: cmd-parse.c:305
static void cmd_parse_free_commands(struct cmd_parse_commands *)
Definition: cmd-parse.c:368
const short yycheck[]
Definition: cmd-parse.c:196
unsigned int yystacksize
Definition: cmd-parse.c:318
static char * yylex_token(int)
Definition: cmd-parse.c:1261
#define ELSE
Definition: cmd-parse.c:100
static char * yylex_format(void)
Definition: cmd-parse.c:1028
int yynerrs
Definition: cmd-parse.c:308
static int yylex_token_tilde(char **buf, size_t *len)
Definition: cmd-parse.c:1219
#define YYMAXDEPTH
Definition: cmd-parse.c:302
const short yylen[]
Definition: cmd-parse.c:115
int yyerrflag
Definition: cmd-parse.c:309
static void yylex_append(char **buf, size_t *len, const char *add, size_t addlen)
Definition: cmd-parse.c:804
const short yydgoto[]
Definition: cmd-parse.c:134
TAILQ_HEAD(cmd_parse_commands, cmd_parse_command)
short * yyssp
Definition: cmd-parse.c:311
static struct cmd_parse_commands * cmd_parse_run_parser(char **cause)
Definition: cmd-parse.c:404
static struct cmd_parse_state parse_state
Definition: cmd-parse.c:67
struct cmd_parse_result * cmd_parse_from_buffer(const void *buf, size_t len, struct cmd_parse_input *pi)
Definition: cmd-parse.c:667
static struct cmd_parse_result * cmd_parse_build_commands(struct cmd_parse_commands *cmds, struct cmd_parse_input *pi)
Definition: cmd-parse.c:453
YYSTYPE yylval
Definition: cmd-parse.c:314
static int yylex_token_variable(char **buf, size_t *len)
Definition: cmd-parse.c:1167
#define YYERRCODE
Definition: cmd-parse.c:106
const short yyrindex[]
Definition: cmd-parse.c:149
short * yyss
Definition: cmd-parse.c:315
#define TOKEN
Definition: cmd-parse.c:104
#define YYPREFIX
Definition: cmd-parse.c:11
YYSTYPE * yyvs
Definition: cmd-parse.c:317
#define YYFINAL
Definition: cmd-parse.c:227
static int yygrowstack(void)
Definition: cmd-parse.c:1366
static int yylex(void)
Definition: cmd-parse.c:898
enum cmd_parse_status cmd_parse_and_insert(const char *s, struct cmd_parse_input *pi, struct cmdq_item *after, struct cmdq_state *state, char **error)
Definition: cmd-parse.c:615
#define YYTABLESIZE
Definition: cmd-parse.c:164
struct cmd_parse_result * cmd_parse_from_string(const char *s, struct cmd_parse_input *pi)
Definition: cmd-parse.c:596
static int yylex_getc(void)
Definition: cmd-parse.c:848
static int yylex_is_var(char ch, int first)
Definition: cmd-parse.c:794
const short yygindex[]
Definition: cmd-parse.c:159
#define YY_SIZE_MAX
static void yylex_append1(char **buf, size_t *len, char add)
Definition: cmd-parse.c:814
const short yytable[]
Definition: cmd-parse.c:165
static int yylex_getc1(void)
Definition: cmd-parse.c:820
static int yyparse(void)
Definition: cmd-parse.c:1418
static struct cmd_parse_commands * cmd_parse_do_file(FILE *f, struct cmd_parse_input *pi, char **cause)
Definition: cmd-parse.c:429
#define ERROR
Definition: cmd-parse.c:97
static char * yylex_get_word(int ch)
Definition: cmd-parse.c:879
static void yylex_ungetc(int ch)
Definition: cmd-parse.c:837
static char * cmd_parse_get_error(const char *, u_int, const char *)
Definition: cmd-parse.c:323
struct cmd_parse_result * cmd_parse_from_file(FILE *f, struct cmd_parse_input *pi)
Definition: cmd-parse.c:573
int yychar
Definition: cmd-parse.c:310
static struct cmd_parse_commands * cmd_parse_new_commands(void)
Definition: cmd-parse.c:358
static char * cmd_parse_commands_to_string(struct cmd_parse_commands *)
Definition: cmd-parse.c:380
struct cmd_parse_result * cmd_parse_from_arguments(int argc, char **argv, struct cmd_parse_input *pi)
Definition: cmd-parse.c:697
int yydebug
Definition: cmd-parse.c:307
#define ELIF
Definition: cmd-parse.c:101
#define EQUALS
Definition: cmd-parse.c:105
#define HIDDEN
Definition: cmd-parse.c:98
static void cmd_parse_print_commands(struct cmd_parse_input *, u_int, struct cmd_list *)
Definition: cmd-parse.c:335
#define IF
Definition: cmd-parse.c:99
YYSTYPE * yyvsp
Definition: cmd-parse.c:312
static int yyerror(const char *,...)
Definition: cmd-parse.c:774
#define FORMAT
Definition: cmd-parse.c:103
static struct cmd_parse_commands * cmd_parse_do_buffer(const char *buf, size_t len, struct cmd_parse_input *pi, char **cause)
Definition: cmd-parse.c:440
#define YYMAXTOKEN
Definition: cmd-parse.c:231
const short yylhs[]
Definition: cmd-parse.c:107
enum cmd_parse_status cmd_parse_and_append(const char *s, struct cmd_parse_input *pi, struct client *c, struct cmdq_state *state, char **error)
Definition: cmd-parse.c:641
static void cmd_parse_free_command(struct cmd_parse_command *)
Definition: cmd-parse.c:351
YYSTYPE yyval
Definition: cmd-parse.c:313
const short yysindex[]
Definition: cmd-parse.c:139
const short yydefred[]
Definition: cmd-parse.c:123
static int yylex_token_escape(char **buf, size_t *len)
Definition: cmd-parse.c:1068
#define ENDIF
Definition: cmd-parse.c:102
short * yysslim
Definition: cmd-parse.c:316
void cmdq_print(struct cmdq_item *item, const char *fmt,...)
Definition: cmd-queue.c:792
struct cmdq_item * cmdq_get_command(struct cmd_list *cmdlist, struct cmdq_state *state)
Definition: cmd-queue.c:474
struct cmdq_item * cmdq_append(struct client *c, struct cmdq_item *item)
Definition: cmd-queue.c:288
struct cmdq_item * cmdq_insert_after(struct cmdq_item *after, struct cmdq_item *item)
Definition: cmd-queue.c:312
struct cmd * cmd_parse(int argc, char **argv, const char *file, u_int line, char **cause)
Definition: cmd.c:498
struct cmd_list * cmd_list_new(void)
Definition: cmd.c:576
void cmd_list_move(struct cmd_list *cmdlist, struct cmd_list *from)
Definition: cmd.c:598
char * cmd_list_print(struct cmd_list *cmdlist, int escaped)
Definition: cmd.c:623
char ** cmd_copy_argv(int argc, char **argv)
Definition: cmd.c:327
void cmd_prepend_argv(int *argc, char ***argv, char *arg)
Definition: cmd.c:250
char * cmd_stringify_argv(int argc, char **argv)
Definition: cmd.c:357
void cmd_list_free(struct cmd_list *cmdlist)
Definition: cmd.c:606
char * cmd_get_alias(const char *name)
Definition: cmd.c:417
void cmd_append_argv(int *argc, char ***argv, char *arg)
Definition: cmd.c:267
void cmd_list_append(struct cmd_list *cmdlist, struct cmd *cmd)
Definition: cmd.c:590
void cmd_free_argv(int argc, char **argv)
Definition: cmd.c:344
void cmd_log_argv(int argc, char **argv, const char *fmt,...)
Definition: cmd.c:233
void environ_put(struct environ *env, const char *var, int flags)
Definition: environ.c:150
struct environ_entry * environ_find(struct environ *env, const char *name)
Definition: environ.c:99
void format_defaults(struct format_tree *ft, struct client *c, struct session *s, struct winlink *wl, struct window_pane *wp)
Definition: format.c:4684
struct format_tree * format_create(struct client *c, struct cmdq_item *item, int tag, int flags)
Definition: format.c:3042
char * format_expand(struct format_tree *ft, const char *fmt)
Definition: format.c:4609
void format_free(struct format_tree *ft)
Definition: format.c:3066
int format_true(const char *s)
Definition: format.c:3471
const char * name
Definition: layout-set.c:38
void fatalx(const char *msg,...)
Definition: log.c:159
void log_debug(const char *msg,...)
Definition: log.c:130
Definition: tmux.h:1608
struct window_pane * wp
Definition: tmux.h:1454
struct session * s
Definition: tmux.h:1451
struct winlink * wl
Definition: tmux.h:1452
struct cmdq_item * item
Definition: tmux.h:1504
u_int line
Definition: tmux.h:1502
struct cmd_find_state fs
Definition: tmux.h:1506
struct client * c
Definition: tmux.h:1505
const char * file
Definition: tmux.h:1501
enum cmd_parse_status status
Definition: tmux.h:1489
char * error
Definition: tmux.h:1491
struct cmd_list * cmdlist
Definition: tmux.h:1490
struct cmd_parse_scope * scope
Definition: cmd-parse.c:64
struct cmd_parse_commands * commands
Definition: cmd-parse.c:62
struct cmd_parse_input * input
Definition: cmd-parse.c:58
const char * buf
Definition: cmd-parse.c:51
char * error
Definition: cmd-parse.c:61
Definition: cmd.c:212
char * alias
Definition: cmd.c:220
int argc
Definition: cmd.c:221
u_int line
Definition: cmd.c:218
const struct cmd_entry * entry
Definition: cmd.c:213
char ** argv
Definition: cmd.c:222
struct cmdq_state * state
Definition: cmd-queue.c:55
Definition: tmux.h:1160
char * value
Definition: tmux.h:1162
struct environ * global_environ
Definition: tmux.c:39
#define CMD_PARSE_PARSEONLY
Definition: tmux.h:1496
#define ENVIRON_HIDDEN
Definition: tmux.h:1165
#define FORMAT_NOJOBS
Definition: tmux.h:1971
#define CMD_PARSE_VERBOSE
Definition: tmux.h:1498
cmd_parse_status
Definition: tmux.h:1483
@ CMD_PARSE_ERROR
Definition: tmux.h:1485
@ CMD_PARSE_EMPTY
Definition: tmux.h:1484
@ CMD_PARSE_SUCCESS
Definition: tmux.h:1486
#define CMD_PARSE_ONEGROUP
Definition: tmux.h:1499
#define FORMAT_NONE
Definition: tmux.h:1973
#define printflike(a, b)
Definition: tmux.h:94
char ** argv
Definition: cmd-parse.c:85
struct YYSTYPE::@2 elif
int argc
Definition: cmd-parse.c:84
int flag
Definition: cmd-parse.c:87
struct cmd_parse_commands * commands
Definition: cmd-parse.c:90
struct YYSTYPE::@1 arguments
char * token
Definition: cmd-parse.c:82
struct cmd_parse_command * command
Definition: cmd-parse.c:93
enum window_copy_cmd_action(* f)(struct window_copy_cmd_state *)
Definition: window-copy.c:2248
const char * command
Definition: window-copy.c:2244
void * xmalloc(size_t size)
Definition: xmalloc.c:27
void * xreallocarray(void *ptr, size_t nmemb, size_t size)
Definition: xmalloc.c:61
void * xrealloc(void *ptr, size_t size)
Definition: xmalloc.c:55
int xasprintf(char **ret, const char *fmt,...)
Definition: xmalloc.c:109
void * xcalloc(size_t nmemb, size_t size)
Definition: xmalloc.c:41
char * xstrdup(const char *str)
Definition: xmalloc.c:89
int xvasprintf(char **ret, const char *fmt, va_list ap)
Definition: xmalloc.c:122