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