|
|
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.