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: }

Defined functions

p_assign defined in line 179; used 3 times
p_function defined in line 20; used 3 times

Defined variables

sccsid defined in line 2; never used
Last modified: 1985-04-25
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1273
Valid CSS Valid XHTML 1.0 Strict