date and time created 84/05/06 18:00:10 by edward
[unix-history] / usr / src / usr.bin / window / parser2.c
CommitLineData
57879fc8 1#ifndef lint
bb4a0c0b 2static char *sccsid = "@(#)parser2.c 3.5 84/05/06";
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;
57879fc8
EW
21 register struct lcmd_arg *ap;
22 register i;
1f12ea41 23 struct value av[LCMD_NARG + 1];
4222244b 24 register struct value *vp;
57879fc8 25
bb4a0c0b
EW
26 if (name != 0)
27 if (c = lcmd_lookup(name))
28 name = c->lc_name;
29 else if (a = alias_lookup(name))
30 name = a->a_name;
31 else {
32 p_error("%s: No such command or alias.", name);
57879fc8
EW
33 flag = 0;
34 }
57879fc8 35
bb4a0c0b
EW
36 for (vp = av; vp < &av[LCMD_NARG + 1]; vp++)
37 vp->v_type = V_ERR;
57879fc8
EW
38
39 for (i = 0;;) {
40 ap = 0;
bb4a0c0b 41 vp = 0;
57879fc8
EW
42 if (p_expr0(&t, flag) < 0)
43 if (!p_synerred() && token == T_MUL) {
44 if (c != 0)
45 if (c->lc_arg[i].arg_name == 0)
bb4a0c0b 46 p_error("%s: Too many arguments.", name);
57879fc8
EW
47 else
48 i++;
49 (void) s_gettok();
50 continue;
51 } else
52 break;
53 if (t.v_type == V_ERR)
54 flag = 0;
55 if (token != T_ASSIGN) {
bb4a0c0b
EW
56 if (i >= LCMD_NARG || c != 0 && c->lc_arg != 0
57 && (ap = c->lc_arg + i)->arg_name == 0) {
58 p_error("%s: Too many arguments.", name);
59 flag = 0;
60 } else
61 vp = &av[i++];
57879fc8
EW
62 } else {
63 char *tmp;
bb4a0c0b
EW
64 if (p_convstr(&t) < 0)
65 goto abort;
66 tmp = t.v_type == V_STR ? t.v_str : 0;
57879fc8
EW
67 (void) s_gettok();
68 if (p_expr(&t, flag) < 0) {
69 if (tmp)
70 str_free(tmp);
71 p_synerror();
72 goto abort;
73 }
74 if (t.v_type == V_ERR)
75 flag = 0;
76 if (tmp) {
bb4a0c0b
EW
77 if (c == 0) {
78 /* an aliase */
79 p_error("%s: Bad alias syntax.", name);
57879fc8 80 flag = 0;
bb4a0c0b
EW
81 } else {
82 for (ap = c->lc_arg, vp = av;
83 ap != 0 && ap->arg_name != 0 &&
84 !str_match(tmp, ap->arg_name,
85 ap->arg_minlen);
86 ap++, vp++)
87 ;
88 if (ap == 0 || ap->arg_name == 0) {
89 p_error("%s: Unknown argument \"%s\".",
90 name, tmp);
91 flag = 0;
92 ap = 0;
93 vp = 0;
94 }
57879fc8
EW
95 }
96 str_free(tmp);
97 }
98 }
99 if (ap != 0) {
4222244b 100 if (vp->v_type != V_ERR) {
57879fc8 101 p_error("%s: Argument %d (%s) duplicated.",
bb4a0c0b 102 name, ap - c->lc_arg + 1,
57879fc8 103 ap->arg_name);
57879fc8 104 flag = 0;
1f12ea41 105 vp = 0;
57879fc8
EW
106 } else if (t.v_type == V_ERR) {
107 /* do nothing */
108 } else if (ap->arg_type == ARG_NUM && t.v_type != V_NUM
109 || ap->arg_type == ARG_STR && t.v_type != V_STR) {
110 p_error("%s: Argument %d (%s) type mismatch.",
bb4a0c0b 111 name, ap - c->lc_arg + 1,
57879fc8 112 ap->arg_name);
57879fc8 113 flag = 0;
1f12ea41
EW
114 vp = 0;
115 }
57879fc8 116 }
1f12ea41
EW
117 if (vp != 0)
118 *vp = t;
119 else
120 val_free(t);
57879fc8
EW
121 if (token == T_COMMA)
122 (void) s_gettok();
123 }
124
125 if (p_erred())
126 flag = 0;
127 if (token != T_RP && token != T_EOL && token != T_EOF)
1f12ea41 128 flag = 0; /* look for legal follow set */
57879fc8
EW
129 v->v_type = V_ERR;
130 if (flag)
bb4a0c0b
EW
131 if (c != 0)
132 (*c->lc_func)(v, av);
133 else
134 if (dolongcmd(a->a_buf, av, i) < 0)
135 p_memerror();
136 if (p_abort()) {
137 val_free(*v);
138 v->v_type = V_ERR;
139 goto abort;
140 }
141 for (vp = av; vp < &av[LCMD_NARG]; vp++)
142 val_free(*vp);
57879fc8
EW
143 return 0;
144abort:
bb4a0c0b
EW
145 for (vp = av; vp < &av[LCMD_NARG]; vp++)
146 val_free(*vp);
57879fc8
EW
147 return -1;
148}
149
150p_assign(name, v, flag)
151char *name;
152struct value *v;
153char flag;
154{
155 (void) s_gettok();
156
157 if (p_expr(v, flag) < 0) {
158 p_synerror();
159 return -1;
160 }
161 switch (v->v_type) {
162 case V_STR:
163 case V_NUM:
164 if (flag && var_set(name, v) == 0) {
165 p_memerror();
166 val_free(*v);
167 return -1;
168 }
169 break;
170 }
171 return 0;
172}