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