|
|
1.1 root 1: /*
2: * Copyright (c) 1983 Regents of the University of California.
3: * All rights reserved.
4: *
5: * This code is derived from software contributed to Berkeley by
6: * Edward Wang at The University of California, Berkeley.
7: *
8: * Redistribution and use in source and binary forms are permitted provided
9: * that: (1) source distributions retain this entire copyright notice and
10: * comment, and (2) distributions including binaries display the following
11: * acknowledgement: ``This product includes software developed by the
12: * University of California, Berkeley and its contributors'' in the
13: * documentation or other materials provided with the distribution and in
14: * all advertising materials mentioning features or use of this software.
15: * Neither the name of the University nor the names of its contributors may
16: * be used to endorse or promote products derived from this software without
17: * specific prior written permission.
18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21: */
22:
23: #ifndef lint
24: static char sccsid[] = "@(#)parser2.c 3.14 (Berkeley) 6/6/90";
25: #endif /* not lint */
26:
27: #include "parser.h"
28: #include "var.h"
29: #include "lcmd.h"
30: #include "alias.h"
31:
32: /*
33: * name == 0 means we don't have a function name but
34: * want to parse the arguments anyway. flag == 0 in this case.
35: */
36: p_function(name, v, flag)
37: char *name;
38: register struct value *v;
39: {
40: struct value t;
41: register struct lcmd_tab *c = 0;
42: register struct alias *a = 0;
43: register struct lcmd_arg *ap; /* this arg */
44: struct lcmd_arg *lp = 0; /* list arg */
45: register i;
46: struct value av[LCMD_NARG + 1];
47: register struct value *vp;
48:
49: if (name != 0)
50: if (c = lcmd_lookup(name))
51: name = c->lc_name;
52: else if (a = alias_lookup(name))
53: name = a->a_name;
54: else {
55: p_error("%s: No such command or alias.", name);
56: flag = 0;
57: }
58:
59: for (vp = av; vp < &av[LCMD_NARG + 1]; vp++)
60: vp->v_type = V_ERR;
61:
62: if (token == T_LP)
63: (void) s_gettok();
64: i = 0;
65: for (;;) {
66: ap = 0;
67: vp = 0;
68: if (token == T_COMMA) /* null argument */
69: t.v_type = V_ERR;
70: else {
71: if (p_expr0(&t, flag) < 0)
72: break;
73: if (t.v_type == V_ERR)
74: flag = 0;
75: }
76: if (token != T_ASSIGN) {
77: if (i >= LCMD_NARG ||
78: c != 0 && (ap = lp) == 0 &&
79: (ap = c->lc_arg + i)->arg_name == 0) {
80: p_error("%s: Too many arguments.", name);
81: flag = 0;
82: } else
83: vp = &av[i++];
84: } else {
85: char *tmp;
86: if (p_convstr(&t) < 0)
87: goto abort;
88: tmp = t.v_type == V_STR ? t.v_str : 0;
89: (void) s_gettok();
90: if (p_expr(&t, flag) < 0) {
91: if (tmp)
92: str_free(tmp);
93: p_synerror();
94: goto abort;
95: }
96: if (t.v_type == V_ERR)
97: flag = 0;
98: if (tmp) {
99: if (c == 0) {
100: /* an aliase */
101: p_error("%s: Bad alias syntax.", name);
102: flag = 0;
103: } else {
104: for (ap = c->lc_arg, vp = av;
105: ap != 0 && ap->arg_name != 0 &&
106: (*ap->arg_name == '\0' ||
107: !str_match(tmp, ap->arg_name,
108: ap->arg_minlen));
109: ap++, vp++)
110: ;
111: if (ap == 0 || ap->arg_name == 0) {
112: p_error("%s: Unknown argument \"%s\".",
113: name, tmp);
114: flag = 0;
115: ap = 0;
116: vp = 0;
117: }
118: }
119: str_free(tmp);
120: }
121: }
122: if (ap != 0) {
123: if (ap->arg_flags & ARG_LIST) {
124: i = vp - av + 1;
125: lp = ap;
126: }
127: if (vp->v_type != V_ERR) {
128: if (*ap->arg_name)
129: p_error("%s: Argument %d (%s) duplicated.",
130: name, vp - av + 1,
131: ap->arg_name);
132: else
133: p_error("%s: Argument %d duplicated.",
134: name, vp - av + 1);
135: flag = 0;
136: vp = 0;
137: } else if (t.v_type == V_ERR) {
138: /* do nothing */
139: } else if ((ap->arg_flags&ARG_TYPE) == ARG_NUM &&
140: t.v_type != V_NUM ||
141: (ap->arg_flags&ARG_TYPE) == ARG_STR &&
142: t.v_type != V_STR) {
143: if (*ap->arg_name)
144: p_error("%s: Argument %d (%s) type mismatch.",
145: name, vp - av + 1,
146: ap->arg_name);
147: else
148: p_error("%s: Argument %d type mismatch.",
149: name, vp - av + 1);
150: flag = 0;
151: vp = 0;
152: }
153: }
154: if (vp != 0)
155: *vp = t;
156: else
157: val_free(t);
158: if (token == T_COMMA)
159: (void) s_gettok();
160: }
161:
162: if (p_erred())
163: flag = 0;
164: if (token == T_RP)
165: (void) s_gettok();
166: else if (token != T_EOL && token != T_EOF)
167: flag = 0; /* look for legal follow set */
168: v->v_type = V_ERR;
169: if (flag)
170: if (c != 0)
171: (*c->lc_func)(v, av);
172: else
173: if (a->a_flags & A_INUSE)
174: p_error("%s: Recursive alias.", a->a_name);
175: else {
176: a->a_flags |= A_INUSE;
177: if (dolongcmd(a->a_buf, av, i) < 0)
178: p_memerror();
179: a->a_flags &= ~A_INUSE;
180: }
181: if (p_abort()) {
182: val_free(*v);
183: v->v_type = V_ERR;
184: goto abort;
185: }
186: for (vp = av; vp < &av[LCMD_NARG]; vp++)
187: val_free(*vp);
188: return 0;
189: abort:
190: for (vp = av; vp < &av[LCMD_NARG]; vp++)
191: val_free(*vp);
192: return -1;
193: }
194:
195: p_assign(name, v, flag)
196: char *name;
197: struct value *v;
198: char flag;
199: {
200: (void) s_gettok();
201:
202: if (p_expr(v, flag) < 0) {
203: p_synerror();
204: return -1;
205: }
206: switch (v->v_type) {
207: case V_STR:
208: case V_NUM:
209: if (flag && var_set(name, v) == 0) {
210: p_memerror();
211: val_free(*v);
212: return -1;
213: }
214: break;
215: }
216: return 0;
217: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.