l_time(): give the rss fields more room
[unix-history] / usr / src / usr.bin / window / parser5.c
index d21fce8..80ed175 100644 (file)
@@ -1,12 +1,29 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)parser5.c  3.6 %G%";
-#endif
+static char sccsid[] = "@(#)parser5.c  3.11 (Berkeley) %G%";
+#endif /* not lint */
 
 #include "parser.h"
 #include "var.h"
 
 /*
 
 #include "parser.h"
 #include "var.h"
 
 /*
- * unary $ + - ! ~
+ * unary $ $? + - ! ~
  */
 p_expr11(v, flag)
 register struct value *v;
  */
 p_expr11(v, flag)
 register struct value *v;
@@ -19,6 +36,9 @@ char flag;
        case T_DOLLAR:
                opname = "$";
                break;
        case T_DOLLAR:
                opname = "$";
                break;
+       case T_DQ:
+               opname = "$?";
+               break;
        case T_PLUS:
                opname = "unary +";
                break;
        case T_PLUS:
                opname = "unary +";
                break;
@@ -46,7 +66,7 @@ char flag;
                case T_MINUS:
                case T_NOT:
                case T_COMP:
                case T_MINUS:
                case T_NOT:
                case T_COMP:
-                       p_error("Numeric value required for %s.", opname);
+                       p_error("%s: Numeric operand required.", opname);
                        str_free(v->v_str);
                        v->v_type = V_ERR;
                        return 0;
                        str_free(v->v_str);
                        v->v_type = V_ERR;
                        return 0;
@@ -56,36 +76,38 @@ char flag;
                return 0;
        }
        switch (op) {
                return 0;
        }
        switch (op) {
-       case T_DOLLAR: {
-               struct var *r;
+       case T_DOLLAR:
+       case T_DQ:
                if (v->v_type == V_NUM) {
                if (v->v_type == V_NUM) {
-                       v->v_num--;
-                       if (cx.x_type != X_BUF || cx.x_arg == 0 ||
-                           v->v_num < 0 || v->v_num >= cx.x_narg) {
+                       int tmp = cx.x_type == X_BUF && cx.x_arg != 0 &&
+                               v->v_num > 0 && v->v_num <= cx.x_narg;
+                       if (op == T_DQ)
+                               v->v_num = tmp;
+                       else if (tmp)
+                               *v = cx.x_arg[v->v_num - 1];
+                       else {
                                p_error("%d: No such argument.", v->v_num);
                                v->v_type = V_ERR;
                                p_error("%d: No such argument.", v->v_num);
                                v->v_type = V_ERR;
-                               return 0;
                        }
                        }
-                       if (flag)
-                               *v = cx.x_arg[v->v_num];
                } else {
                } else {
-                       if ((r = var_lookup(v->v_str)) == 0) {
-                               p_error("%s: Undefined variable.", v->v_str);
-                               str_free(v->v_str);
+                       char *name = v->v_str;
+                       struct var *r = var_lookup(name);
+                       if (op == T_DQ) {
+                               v->v_type = V_NUM;
+                               v->v_num = r != 0;
+                       } else if (r != 0)
+                               *v = r->r_val;
+                       else {
+                               p_error("%s: Undefined variable.", name);
                                v->v_type = V_ERR;
                                v->v_type = V_ERR;
-                               return 0;
                        }
                        }
-                       str_free(v->v_str);
-                       if (flag)
-                               *v = r->r_val;
+                       str_free(name);
                }
                }
-               if (v->v_type == V_STR
-                   && (v->v_str = str_cpy(v->v_str)) == 0) {
+               if (v->v_type == V_STR && (v->v_str = str_cpy(v->v_str)) == 0) {
                        p_memerror();
                        return -1;
                }
                break;
                        p_memerror();
                        return -1;
                }
                break;
-               }
        case T_MINUS:
                v->v_num = - v->v_num;
                break;
        case T_MINUS:
                v->v_num = - v->v_num;
                break;
@@ -102,7 +124,6 @@ char flag;
 /*
  * string, number, ( expr )
  * Plus function calls.
 /*
  * string, number, ( expr )
  * Plus function calls.
- * Also we map % into string.
  *
  * Always return v_type == V_ERR when flag == 0.
  */
  *
  * Always return v_type == V_ERR when flag == 0.
  */
@@ -112,13 +133,6 @@ char flag;
 {
        v->v_type = V_ERR;
        switch (token) {
 {
        v->v_type = V_ERR;
        switch (token) {
-       case T_MOD:
-               if (flag) {
-                       v->v_type = V_STR;
-                       v->v_str = str_cpy("%");
-               }
-               (void) s_gettok();
-               break;
        case T_NUM:
                if (flag) {
                        v->v_type = V_NUM;
        case T_NUM:
                if (flag) {
                        v->v_type = V_NUM;
@@ -153,7 +167,6 @@ char flag;
        while (token == T_LP) {
                char *cmd;
 
        while (token == T_LP) {
                char *cmd;
 
-               (void) s_gettok();
                if (p_convstr(v) < 0)
                        return -1;
                cmd = v->v_type == V_STR ? v->v_str : 0;
                if (p_convstr(v) < 0)
                        return -1;
                cmd = v->v_type == V_STR ? v->v_str : 0;
@@ -164,12 +177,6 @@ char flag;
                }
                if (cmd)
                        str_free(cmd);
                }
                if (cmd)
                        str_free(cmd);
-               if (token != T_RP) {
-                       p_synerror();
-                       val_free(*v);
-                       return -1;
-               }
-               (void) s_gettok();
        }
        return 0;
 }
        }
        return 0;
 }