fix sccsid to use keywords and modern initialization syntax
[unix-history] / usr / src / usr.bin / window / parser5.c
CommitLineData
dc2a07ab 1#ifndef lint
60de5df9 2static char sccsid[] = "@(#)parser5.c 3.9 %G%";
dc2a07ab
EW
3#endif
4
60de5df9
EW
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
dc2a07ab 11#include "parser.h"
0173496c 12#include "var.h"
dc2a07ab
EW
13
14/*
5119bdf8 15 * unary $ $? + - ! ~
dc2a07ab
EW
16 */
17p_expr11(v, flag)
18register struct value *v;
19char flag;
20{
21 int op;
22 char *opname;
23
24 switch (token) {
25 case T_DOLLAR:
26 opname = "$";
27 break;
5119bdf8
EW
28 case T_DQ:
29 opname = "$?";
30 break;
dc2a07ab
EW
31 case T_PLUS:
32 opname = "unary +";
33 break;
34 case T_MINUS:
35 opname = "unary -";
36 break;
37 case T_NOT:
38 opname = "!";
39 break;
40 case T_COMP:
41 opname = "~";
42 break;
43 default:
44 return p_expr12(v, flag);
45 }
46 op = token;
47 (void) s_gettok();
48 if (p_expr11(v, flag) < 0)
49 return -1;
50 switch (v->v_type) {
51 case V_NUM:
dc2a07ab
EW
52 break;
53 case V_STR:
54 switch (op) {
55 case T_MINUS:
56 case T_NOT:
57 case T_COMP:
5119bdf8 58 p_error("%s: Numeric operand required.", opname);
dc2a07ab
EW
59 str_free(v->v_str);
60 v->v_type = V_ERR;
61 return 0;
62 }
63 break;
64 case V_ERR:
65 return 0;
66 }
67 switch (op) {
5119bdf8
EW
68 case T_DOLLAR:
69 case T_DQ:
bb4a0c0b 70 if (v->v_type == V_NUM) {
5119bdf8
EW
71 int tmp = cx.x_type == X_BUF && cx.x_arg != 0 &&
72 v->v_num > 0 && v->v_num <= cx.x_narg;
73 if (op == T_DQ)
74 v->v_num = tmp;
75 else if (tmp)
76 *v = cx.x_arg[v->v_num - 1];
77 else {
bb4a0c0b
EW
78 p_error("%d: No such argument.", v->v_num);
79 v->v_type = V_ERR;
bb4a0c0b 80 }
bb4a0c0b 81 } else {
5119bdf8
EW
82 char *name = v->v_str;
83 struct var *r = var_lookup(name);
84 if (op == T_DQ) {
85 v->v_type = V_NUM;
86 v->v_num = r != 0;
87 } else if (r != 0)
88 *v = r->r_val;
89 else {
90 p_error("%s: Undefined variable.", name);
bb4a0c0b 91 v->v_type = V_ERR;
bb4a0c0b 92 }
5119bdf8 93 str_free(name);
dc2a07ab 94 }
5119bdf8 95 if (v->v_type == V_STR && (v->v_str = str_cpy(v->v_str)) == 0) {
bb4a0c0b
EW
96 p_memerror();
97 return -1;
dc2a07ab
EW
98 }
99 break;
dc2a07ab
EW
100 case T_MINUS:
101 v->v_num = - v->v_num;
102 break;
103 case T_NOT:
104 v->v_num = ! v->v_num;
105 break;
106 case T_COMP:
107 v->v_num = ~ v->v_num;
108 break;
109 }
110 return 0;
111}
112
113/*
114 * string, number, ( expr )
115 * Plus function calls.
dc2a07ab
EW
116 *
117 * Always return v_type == V_ERR when flag == 0.
118 */
119p_expr12(v, flag)
120register struct value *v;
121char flag;
122{
123 v->v_type = V_ERR;
dc2a07ab 124 switch (token) {
dc2a07ab 125 case T_NUM:
dc2a07ab
EW
126 if (flag) {
127 v->v_type = V_NUM;
128 v->v_num = token_num;
129 }
130 (void) s_gettok();
131 break;
132 case T_STR:
dc2a07ab
EW
133 if (flag) {
134 v->v_type = V_STR;
135 v->v_str = token_str;
136 } else
137 str_free(token_str);
138 (void) s_gettok();
139 break;
140 case T_LP:
141 (void) s_gettok();
142 if (p_expr(v, flag) < 0) {
143 p_synerror();
144 return -1;
145 }
146 if (token != T_RP) {
147 p_synerror();
148 val_free(*v);
149 return -1;
150 }
151 (void) s_gettok();
152 break;
153 default:
dc2a07ab
EW
154 return -1;
155 }
156 while (token == T_LP) {
157 char *cmd;
158
bb4a0c0b
EW
159 if (p_convstr(v) < 0)
160 return -1;
161 cmd = v->v_type == V_STR ? v->v_str : 0;
dc2a07ab 162 if (p_function(cmd, v, flag) < 0) {
f8e2d916
EW
163 if (cmd)
164 str_free(cmd);
dc2a07ab
EW
165 return -1;
166 }
f8e2d916
EW
167 if (cmd)
168 str_free(cmd);
dc2a07ab
EW
169 }
170 return 0;
171}