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