new io scheme
[unix-history] / usr / src / usr.bin / window / parser2.c
CommitLineData
57879fc8 1#ifndef lint
0173496c 2static char *sccsid = "@(#)parser2.c 3.2 84/01/13";
57879fc8
EW
3#endif
4
5#include "parser.h"
0173496c
EW
6#include "var.h"
7#include "lcmd.h"
57879fc8
EW
8
9/*
10 * name == 0 means we don't have a function name but
11 * want to parse the arguments anyway. flag == 0 in this case.
12 */
13p_function(name, v, flag)
14char *name;
15register struct value *v;
16{
17 struct value t;
18 register struct lcmd_tab *c;
19 register struct lcmd_arg *ap;
20 register i;
21
22 if (name != 0) {
23 if ((c = lcmd_lookup(name)) == 0) {
24 p_error("%s: No such command.", name);
25 flag = 0;
26 }
27 } else
28 c = 0;
29
30 if (c != 0)
31 for (ap = c->lc_arg; ap->arg_name != 0; ap++)
32 ap->arg_val.v_type = V_ERR;
33
34 for (i = 0;;) {
35 ap = 0;
36 if (p_expr0(&t, flag) < 0)
37 if (!p_synerred() && token == T_MUL) {
38 if (c != 0)
39 if (c->lc_arg[i].arg_name == 0)
40 p_error("%s: Too many arguments.", c->lc_name);
41 else
42 i++;
43 (void) s_gettok();
44 continue;
45 } else
46 break;
47 if (t.v_type == V_ERR)
48 flag = 0;
49 if (token != T_ASSIGN) {
50 if (c != 0) {
51 ap = &c->lc_arg[i];
52 if (ap->arg_name == 0) {
53 p_error("%s: Too many arguments.",
54 c->lc_name);
55 val_free(t);
56 ap = 0;
57 flag = 0;
58 } else
59 i++;
60 }
61 } else {
62 char *tmp;
63 switch (t.v_type) {
64 case V_ERR:
65 tmp = 0;
66 break;
67 case V_NUM:
68 if ((tmp = str_itoa(t.v_num)) == 0) {
69 p_memerror();
70 goto abort;
71 }
72 break;
73 case V_STR:
74 tmp = t.v_str;
75 break;
76 }
77 (void) s_gettok();
78 if (p_expr(&t, flag) < 0) {
79 if (tmp)
80 str_free(tmp);
81 p_synerror();
82 goto abort;
83 }
84 if (t.v_type == V_ERR)
85 flag = 0;
86 if (tmp) {
87 /* we know c != 0 */
88 for (ap = c->lc_arg; ap->arg_name != 0; ap++)
89 if (str_match(tmp, ap->arg_name,
90 ap->arg_minlen))
91 break;
92 if (ap->arg_name == 0) {
93 p_error("%s: Unknown argument \"%s\".",
94 c->lc_name, tmp);
95 val_free(t);
96 flag = 0;
97 ap = 0;
98 }
99 str_free(tmp);
100 }
101 }
102 if (ap != 0) {
103 if (ap->arg_val.v_type != V_ERR) {
104 p_error("%s: Argument %d (%s) duplicated.",
105 c->lc_name, ap - c->lc_arg + 1,
106 ap->arg_name);
107 val_free(t);
108 flag = 0;
109 } else if (t.v_type == V_ERR) {
110 /* do nothing */
111 } else if (ap->arg_type == ARG_NUM && t.v_type != V_NUM
112 || ap->arg_type == ARG_STR && t.v_type != V_STR) {
113 p_error("%s: Argument %d (%s) type mismatch.",
114 c->lc_name, ap - c->lc_arg + 1,
115 ap->arg_name);
116 val_free(t);
117 flag = 0;
118 } else
119 ap->arg_val = t;
120 }
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)
128 flag = 0; /* look ahead a bit */
129 v->v_type = V_ERR;
130 if (flag)
131 (*c->lc_func)(v);
132 if (c != 0)
133 for (ap = c->lc_arg; ap->arg_name != 0; ap++)
134 val_free(ap->arg_val);
135 return 0;
136abort:
137 if (c != 0)
138 for (ap = c->lc_arg; ap->arg_name != 0; ap++)
139 val_free(ap->arg_val);
140 return -1;
141}
142
143p_assign(name, v, flag)
144char *name;
145struct value *v;
146char flag;
147{
148 (void) s_gettok();
149
150 if (p_expr(v, flag) < 0) {
151 p_synerror();
152 return -1;
153 }
154 switch (v->v_type) {
155 case V_STR:
156 case V_NUM:
157 if (flag && var_set(name, v) == 0) {
158 p_memerror();
159 val_free(*v);
160 return -1;
161 }
162 break;
163 }
164 return 0;
165}