new ARG_LIST flag for commands
[unix-history] / usr / src / usr.bin / window / parser2.c
CommitLineData
57879fc8 1#ifndef lint
855d0f8f 2static char sccsid[] = "@(#)parser2.c 3.8 %G%";
57879fc8
EW
3#endif
4
5#include "parser.h"
0173496c
EW
6#include "var.h"
7#include "lcmd.h"
bb4a0c0b 8#include "alias.h"
57879fc8
EW
9
10/*
11 * name == 0 means we don't have a function name but
12 * want to parse the arguments anyway. flag == 0 in this case.
13 */
14p_function(name, v, flag)
15char *name;
16register struct value *v;
17{
18 struct value t;
bb4a0c0b
EW
19 register struct lcmd_tab *c = 0;
20 register struct alias *a = 0;
855d0f8f
EW
21 register struct lcmd_arg *ap; /* this arg */
22 struct lcmd_arg *lp = 0; /* list arg */
57879fc8 23 register i;
1f12ea41 24 struct value av[LCMD_NARG + 1];
4222244b 25 register struct value *vp;
57879fc8 26
bb4a0c0b
EW
27 if (name != 0)
28 if (c = lcmd_lookup(name))
29 name = c->lc_name;
30 else if (a = alias_lookup(name))
31 name = a->a_name;
32 else {
33 p_error("%s: No such command or alias.", name);
57879fc8
EW
34 flag = 0;
35 }
57879fc8 36
bb4a0c0b
EW
37 for (vp = av; vp < &av[LCMD_NARG + 1]; vp++)
38 vp->v_type = V_ERR;
57879fc8 39
855d0f8f 40 for (i = 0; p_expr0(&t, flag) >= 0;) {
57879fc8
EW
41 if (t.v_type == V_ERR)
42 flag = 0;
855d0f8f
EW
43 ap = 0;
44 vp = 0;
57879fc8 45 if (token != T_ASSIGN) {
855d0f8f
EW
46 if (i >= LCMD_NARG ||
47 c != 0 && (ap = lp) == 0 &&
48 (ap = c->lc_arg + i)->arg_name == 0) {
bb4a0c0b
EW
49 p_error("%s: Too many arguments.", name);
50 flag = 0;
51 } else
52 vp = &av[i++];
57879fc8
EW
53 } else {
54 char *tmp;
bb4a0c0b
EW
55 if (p_convstr(&t) < 0)
56 goto abort;
57 tmp = t.v_type == V_STR ? t.v_str : 0;
57879fc8
EW
58 (void) s_gettok();
59 if (p_expr(&t, flag) < 0) {
60 if (tmp)
61 str_free(tmp);
62 p_synerror();
63 goto abort;
64 }
65 if (t.v_type == V_ERR)
66 flag = 0;
67 if (tmp) {
bb4a0c0b
EW
68 if (c == 0) {
69 /* an aliase */
70 p_error("%s: Bad alias syntax.", name);
57879fc8 71 flag = 0;
bb4a0c0b
EW
72 } else {
73 for (ap = c->lc_arg, vp = av;
74 ap != 0 && ap->arg_name != 0 &&
855d0f8f
EW
75 (*ap->arg_name == '\0' ||
76 !str_match(tmp, ap->arg_name,
77 ap->arg_minlen));
bb4a0c0b
EW
78 ap++, vp++)
79 ;
80 if (ap == 0 || ap->arg_name == 0) {
81 p_error("%s: Unknown argument \"%s\".",
82 name, tmp);
83 flag = 0;
84 ap = 0;
85 vp = 0;
86 }
57879fc8
EW
87 }
88 str_free(tmp);
89 }
90 }
91 if (ap != 0) {
855d0f8f
EW
92 if (ap->arg_flags & ARG_LIST) {
93 i = vp - av + 1;
94 lp = ap;
95 }
4222244b 96 if (vp->v_type != V_ERR) {
855d0f8f
EW
97 if (*ap->arg_name)
98 p_error("%s: Argument %d (%s) duplicated.",
99 name, vp - av + 1,
100 ap->arg_name);
101 else
102 p_error("%s: Argument %d duplicated.",
103 name, vp - av + 1);
57879fc8 104 flag = 0;
1f12ea41 105 vp = 0;
57879fc8
EW
106 } else if (t.v_type == V_ERR) {
107 /* do nothing */
855d0f8f
EW
108 } else if ((ap->arg_flags&ARG_TYPE) == ARG_NUM &&
109 t.v_type != V_NUM ||
110 (ap->arg_flags&ARG_TYPE) == ARG_STR &&
111 t.v_type != V_STR) {
112 if (*ap->arg_name)
113 p_error("%s: Argument %d (%s) type mismatch.",
114 name, vp - av + 1,
115 ap->arg_name);
116 else
117 p_error("%s: Argument %d type mismatch.",
118 name, vp - av + 1);
57879fc8 119 flag = 0;
1f12ea41
EW
120 vp = 0;
121 }
57879fc8 122 }
1f12ea41
EW
123 if (vp != 0)
124 *vp = t;
125 else
126 val_free(t);
57879fc8
EW
127 if (token == T_COMMA)
128 (void) s_gettok();
129 }
130
131 if (p_erred())
132 flag = 0;
133 if (token != T_RP && token != T_EOL && token != T_EOF)
1f12ea41 134 flag = 0; /* look for legal follow set */
57879fc8
EW
135 v->v_type = V_ERR;
136 if (flag)
bb4a0c0b
EW
137 if (c != 0)
138 (*c->lc_func)(v, av);
139 else
7293cf8d
EW
140 if (a->a_flags & A_INUSE)
141 p_error("%s: Recursive alias.", a->a_name);
142 else {
143 a->a_flags |= A_INUSE;
144 if (dolongcmd(a->a_buf, av, i) < 0)
145 p_memerror();
146 a->a_flags &= ~A_INUSE;
147 }
bb4a0c0b
EW
148 if (p_abort()) {
149 val_free(*v);
150 v->v_type = V_ERR;
151 goto abort;
152 }
153 for (vp = av; vp < &av[LCMD_NARG]; vp++)
154 val_free(*vp);
57879fc8
EW
155 return 0;
156abort:
bb4a0c0b
EW
157 for (vp = av; vp < &av[LCMD_NARG]; vp++)
158 val_free(*vp);
57879fc8
EW
159 return -1;
160}
161
162p_assign(name, v, flag)
163char *name;
164struct value *v;
165char flag;
166{
167 (void) s_gettok();
168
169 if (p_expr(v, flag) < 0) {
170 p_synerror();
171 return -1;
172 }
173 switch (v->v_type) {
174 case V_STR:
175 case V_NUM:
176 if (flag && var_set(name, v) == 0) {
177 p_memerror();
178 val_free(*v);
179 return -1;
180 }
181 break;
182 }
183 return 0;
184}