|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)parser2.c 3.10 4/24/85"; ! 3: #endif ! 4: ! 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: ! 11: #include "parser.h" ! 12: #include "var.h" ! 13: #include "lcmd.h" ! 14: #include "alias.h" ! 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: */ ! 20: p_function(name, v, flag) ! 21: char *name; ! 22: register struct value *v; ! 23: { ! 24: struct value t; ! 25: register struct lcmd_tab *c = 0; ! 26: register struct alias *a = 0; ! 27: register struct lcmd_arg *ap; /* this arg */ ! 28: struct lcmd_arg *lp = 0; /* list arg */ ! 29: register i; ! 30: struct value av[LCMD_NARG + 1]; ! 31: register struct value *vp; ! 32: ! 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); ! 40: flag = 0; ! 41: } ! 42: ! 43: for (vp = av; vp < &av[LCMD_NARG + 1]; vp++) ! 44: vp->v_type = V_ERR; ! 45: ! 46: if (token == T_LP) ! 47: (void) s_gettok(); ! 48: i = 0; ! 49: for (;;) { ! 50: ap = 0; ! 51: vp = 0; ! 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: } ! 60: if (token != T_ASSIGN) { ! 61: if (i >= LCMD_NARG || ! 62: c != 0 && (ap = lp) == 0 && ! 63: (ap = c->lc_arg + i)->arg_name == 0) { ! 64: p_error("%s: Too many arguments.", name); ! 65: flag = 0; ! 66: } else ! 67: vp = &av[i++]; ! 68: } else { ! 69: char *tmp; ! 70: if (p_convstr(&t) < 0) ! 71: goto abort; ! 72: tmp = t.v_type == V_STR ? t.v_str : 0; ! 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) { ! 83: if (c == 0) { ! 84: /* an aliase */ ! 85: p_error("%s: Bad alias syntax.", name); ! 86: flag = 0; ! 87: } else { ! 88: for (ap = c->lc_arg, vp = av; ! 89: ap != 0 && ap->arg_name != 0 && ! 90: (*ap->arg_name == '\0' || ! 91: !str_match(tmp, ap->arg_name, ! 92: ap->arg_minlen)); ! 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: } ! 102: } ! 103: str_free(tmp); ! 104: } ! 105: } ! 106: if (ap != 0) { ! 107: if (ap->arg_flags & ARG_LIST) { ! 108: i = vp - av + 1; ! 109: lp = ap; ! 110: } ! 111: if (vp->v_type != V_ERR) { ! 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); ! 119: flag = 0; ! 120: vp = 0; ! 121: } else if (t.v_type == V_ERR) { ! 122: /* do nothing */ ! 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); ! 134: flag = 0; ! 135: vp = 0; ! 136: } ! 137: } ! 138: if (vp != 0) ! 139: *vp = t; ! 140: else ! 141: val_free(t); ! 142: if (token == T_COMMA) ! 143: (void) s_gettok(); ! 144: } ! 145: ! 146: if (p_erred()) ! 147: flag = 0; ! 148: if (token == T_RP) ! 149: (void) s_gettok(); ! 150: else if (token != T_EOL && token != T_EOF) ! 151: flag = 0; /* look for legal follow set */ ! 152: v->v_type = V_ERR; ! 153: if (flag) ! 154: if (c != 0) ! 155: (*c->lc_func)(v, av); ! 156: else ! 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: } ! 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); ! 172: return 0; ! 173: abort: ! 174: for (vp = av; vp < &av[LCMD_NARG]; vp++) ! 175: val_free(*vp); ! 176: return -1; ! 177: } ! 178: ! 179: p_assign(name, v, flag) ! 180: char *name; ! 181: struct value *v; ! 182: char 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.