mapnl option to window
[unix-history] / usr / src / usr.bin / window / parser2.c
index 929b93d..a9e14fd 100644 (file)
@@ -1,10 +1,11 @@
 #ifndef lint
 #ifndef lint
-static char *sccsid = "@(#)parser2.c   3.3 84/03/23";
+static char sccsid[] = "@(#)parser2.c  3.7 %G%";
 #endif
 
 #include "parser.h"
 #include "var.h"
 #include "lcmd.h"
 #endif
 
 #include "parser.h"
 #include "var.h"
 #include "lcmd.h"
+#include "alias.h"
 
 /*
  * name == 0 means we don't have a function name but
 
 /*
  * name == 0 means we don't have a function name but
@@ -15,31 +16,34 @@ char *name;
 register struct value *v;
 {
        struct value t;
 register struct value *v;
 {
        struct value t;
-       register struct lcmd_tab *c;
+       register struct lcmd_tab *c = 0;
+       register struct alias *a = 0;
        register struct lcmd_arg *ap;
        register i;
        register struct lcmd_arg *ap;
        register i;
-       struct value av[LCMD_NARG];
+       struct value av[LCMD_NARG + 1];
        register struct value *vp;
 
        register struct value *vp;
 
-       if (name != 0) {
-               if ((c = lcmd_lookup(name)) == 0) {
-                       p_error("%s: No such command.", name);
+       if (name != 0)
+               if (c = lcmd_lookup(name))
+                       name = c->lc_name;
+               else if (a = alias_lookup(name))
+                       name = a->a_name;
+               else {
+                       p_error("%s: No such command or alias.", name);
                        flag = 0;
                }
                        flag = 0;
                }
-       } else
-               c = 0;
 
 
-       if (c != 0)
-               for (vp = av; vp < &av[LCMD_NARG]; vp++)
-                       vp->v_type = V_ERR;
+       for (vp = av; vp < &av[LCMD_NARG + 1]; vp++)
+               vp->v_type = V_ERR;
 
        for (i = 0;;) {
                ap = 0;
 
        for (i = 0;;) {
                ap = 0;
+               vp = 0;
                if (p_expr0(&t, flag) < 0)
                        if (!p_synerred() && token == T_MUL) {
                                if (c != 0)
                                        if (c->lc_arg[i].arg_name == 0)
                if (p_expr0(&t, flag) < 0)
                        if (!p_synerred() && token == T_MUL) {
                                if (c != 0)
                                        if (c->lc_arg[i].arg_name == 0)
-                                               p_error("%s: Too many arguments.", c->lc_name);
+                                               p_error("%s: Too many arguments.", name);
                                        else
                                                i++;
                                (void) s_gettok();
                                        else
                                                i++;
                                (void) s_gettok();
@@ -49,34 +53,17 @@ register struct value *v;
                if (t.v_type == V_ERR)
                        flag = 0;
                if (token != T_ASSIGN) {
                if (t.v_type == V_ERR)
                        flag = 0;
                if (token != T_ASSIGN) {
-                       if (c != 0) {
-                               ap = &c->lc_arg[i];
-                               vp = &av[i];
-                               if (ap->arg_name == 0) {
-                                       p_error("%s: Too many arguments.",
-                                               c->lc_name);
-                                       val_free(t);
-                                       ap = 0;
-                                       flag = 0;
-                               } else
-                                       i++;
-                       }
+                       if (i >= LCMD_NARG || c != 0 && c->lc_arg != 0
+                           && (ap = c->lc_arg + i)->arg_name == 0) {
+                               p_error("%s: Too many arguments.", name);
+                               flag = 0;
+                       } else
+                               vp = &av[i++];
                } else {
                        char *tmp;
                } else {
                        char *tmp;
-                       switch (t.v_type) {
-                       case V_ERR:
-                               tmp = 0;
-                               break;
-                       case V_NUM:
-                               if ((tmp = str_itoa(t.v_num)) == 0) {
-                                       p_memerror();
-                                       goto abort;
-                               }
-                               break;
-                       case V_STR:
-                               tmp = t.v_str;
-                               break;
-                       }
+                       if (p_convstr(&t) < 0)
+                               goto abort;
+                       tmp = t.v_type == V_STR ? t.v_str : 0;
                        (void) s_gettok();
                        if (p_expr(&t, flag) < 0) {
                                if (tmp)
                        (void) s_gettok();
                        if (p_expr(&t, flag) < 0) {
                                if (tmp)
@@ -87,18 +74,24 @@ register struct value *v;
                        if (t.v_type == V_ERR)
                                flag = 0;
                        if (tmp) {
                        if (t.v_type == V_ERR)
                                flag = 0;
                        if (tmp) {
-                               /* we know c != 0 */
-                               for (ap = c->lc_arg, vp = av;
-                                    ap->arg_name != 0; ap++, vp++)
-                                       if (str_match(tmp, ap->arg_name,
-                                                       ap->arg_minlen))
-                                               break;
-                               if (ap->arg_name == 0) {
-                                       p_error("%s: Unknown argument \"%s\".",
-                                               c->lc_name, tmp);
-                                       val_free(t);
+                               if (c == 0) {
+                                       /* an aliase */
+                                       p_error("%s: Bad alias syntax.", name);
                                        flag = 0;
                                        flag = 0;
-                                       ap = 0;
+                               } else {
+                                       for (ap = c->lc_arg, vp = av;
+                                            ap != 0 && ap->arg_name != 0 &&
+                                               !str_match(tmp, ap->arg_name,
+                                                       ap->arg_minlen);
+                                            ap++, vp++)
+                                               ;
+                                       if (ap == 0 || ap->arg_name == 0) {
+                                               p_error("%s: Unknown argument \"%s\".",
+                                                       name, tmp);
+                                               flag = 0;
+                                               ap = 0;
+                                               vp = 0;
+                                       }
                                }
                                str_free(tmp);
                        }
                                }
                                str_free(tmp);
                        }
@@ -106,22 +99,25 @@ register struct value *v;
                if (ap != 0) {
                        if (vp->v_type != V_ERR) {
                                p_error("%s: Argument %d (%s) duplicated.",
                if (ap != 0) {
                        if (vp->v_type != V_ERR) {
                                p_error("%s: Argument %d (%s) duplicated.",
-                                       c->lc_name, ap - c->lc_arg + 1,
+                                       name, ap - c->lc_arg + 1,
                                        ap->arg_name);
                                        ap->arg_name);
-                               val_free(t);
                                flag = 0;
                                flag = 0;
+                               vp = 0;
                        } else if (t.v_type == V_ERR) {
                                /* do nothing */
                        } else if (ap->arg_type == ARG_NUM && t.v_type != V_NUM
                            || ap->arg_type == ARG_STR && t.v_type != V_STR) {
                                p_error("%s: Argument %d (%s) type mismatch.",
                        } else if (t.v_type == V_ERR) {
                                /* do nothing */
                        } else if (ap->arg_type == ARG_NUM && t.v_type != V_NUM
                            || ap->arg_type == ARG_STR && t.v_type != V_STR) {
                                p_error("%s: Argument %d (%s) type mismatch.",
-                                       c->lc_name, ap - c->lc_arg + 1,
+                                       name, ap - c->lc_arg + 1,
                                        ap->arg_name);
                                        ap->arg_name);
-                               val_free(t);
                                flag = 0;
                                flag = 0;
-                       } else
-                               *vp = t;
+                               vp = 0;
+                       }
                }
                }
+               if (vp != 0)
+                       *vp = t;
+               else
+                       val_free(t);
                if (token == T_COMMA)
                        (void) s_gettok();
        }
                if (token == T_COMMA)
                        (void) s_gettok();
        }
@@ -129,18 +125,31 @@ register struct value *v;
        if (p_erred())
                flag = 0;
        if (token != T_RP && token != T_EOL && token != T_EOF)
        if (p_erred())
                flag = 0;
        if (token != T_RP && token != T_EOL && token != T_EOF)
-               flag = 0;               /* look ahead a bit */
+               flag = 0;               /* look for legal follow set */
        v->v_type = V_ERR;
        if (flag)
        v->v_type = V_ERR;
        if (flag)
-               (*c->lc_func)(v, av);
-       if (c != 0)
-               for (vp = av; vp < &av[LCMD_NARG]; vp++)
-                       val_free(*vp);
+               if (c != 0)
+                       (*c->lc_func)(v, av);
+               else
+                       if (a->a_flags & A_INUSE)
+                               p_error("%s: Recursive alias.", a->a_name);
+                       else {
+                               a->a_flags |= A_INUSE;
+                               if (dolongcmd(a->a_buf, av, i) < 0)
+                                       p_memerror();
+                               a->a_flags &= ~A_INUSE;
+                       }
+       if (p_abort()) {
+               val_free(*v);
+               v->v_type = V_ERR;
+               goto abort;
+       }
+       for (vp = av; vp < &av[LCMD_NARG]; vp++)
+               val_free(*vp);
        return 0;
 abort:
        return 0;
 abort:
-       if (c != 0)
-               for (vp = av; vp < &av[LCMD_NARG]; vp++)
-                       val_free(*vp);
+       for (vp = av; vp < &av[LCMD_NARG]; vp++)
+               val_free(*vp);
        return -1;
 }
 
        return -1;
 }