Use .Va for errno.
[dragonfly/vkernel-mp.git] / usr.bin / window / parser5.c
blob60aa449598b24289a5b81d9b8544c56fbca21720
1 /*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed to Berkeley by
6 * Edward Wang at The University of California, Berkeley.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
36 * @(#)parser5.c 8.1 (Berkeley) 6/6/93
37 * $FreeBSD: src/usr.bin/window/parser5.c,v 1.1.1.1.14.1 2001/05/17 09:45:00 obrien Exp $
38 * $DragonFly: src/usr.bin/window/parser5.c,v 1.2 2003/06/17 06:29:34 dillon Exp $
41 #include "parser.h"
42 #include "var.h"
45 * unary $ $? + - ! ~
47 p_expr11(v, flag)
48 register struct value *v;
49 char flag;
51 int op;
52 char *opname;
54 switch (token) {
55 case T_DOLLAR:
56 opname = "$";
57 break;
58 case T_DQ:
59 opname = "$?";
60 break;
61 case T_PLUS:
62 opname = "unary +";
63 break;
64 case T_MINUS:
65 opname = "unary -";
66 break;
67 case T_NOT:
68 opname = "!";
69 break;
70 case T_COMP:
71 opname = "~";
72 break;
73 default:
74 return p_expr12(v, flag);
76 op = token;
77 (void) s_gettok();
78 if (p_expr11(v, flag) < 0)
79 return -1;
80 switch (v->v_type) {
81 case V_NUM:
82 break;
83 case V_STR:
84 switch (op) {
85 case T_MINUS:
86 case T_NOT:
87 case T_COMP:
88 p_error("%s: Numeric operand required.", opname);
89 str_free(v->v_str);
90 v->v_type = V_ERR;
91 return 0;
93 break;
94 case V_ERR:
95 return 0;
97 switch (op) {
98 case T_DOLLAR:
99 case T_DQ:
100 if (v->v_type == V_NUM) {
101 int tmp = cx.x_type == X_BUF && cx.x_arg != 0 &&
102 v->v_num > 0 && v->v_num <= cx.x_narg;
103 if (op == T_DQ)
104 v->v_num = tmp;
105 else if (tmp)
106 *v = cx.x_arg[v->v_num - 1];
107 else {
108 p_error("%d: No such argument.", v->v_num);
109 v->v_type = V_ERR;
111 } else {
112 char *name = v->v_str;
113 struct var *r = var_lookup(name);
114 if (op == T_DQ) {
115 v->v_type = V_NUM;
116 v->v_num = r != 0;
117 } else if (r != 0)
118 *v = r->r_val;
119 else {
120 p_error("%s: Undefined variable.", name);
121 v->v_type = V_ERR;
123 str_free(name);
125 if (v->v_type == V_STR && (v->v_str = str_cpy(v->v_str)) == 0) {
126 p_memerror();
127 return -1;
129 break;
130 case T_MINUS:
131 v->v_num = - v->v_num;
132 break;
133 case T_NOT:
134 v->v_num = ! v->v_num;
135 break;
136 case T_COMP:
137 v->v_num = ~ v->v_num;
138 break;
140 return 0;
144 * string, number, ( expr )
145 * Plus function calls.
147 * Always return v_type == V_ERR when flag == 0.
149 p_expr12(v, flag)
150 register struct value *v;
151 char flag;
153 v->v_type = V_ERR;
154 switch (token) {
155 case T_NUM:
156 if (flag) {
157 v->v_type = V_NUM;
158 v->v_num = token_num;
160 (void) s_gettok();
161 break;
162 case T_STR:
163 if (flag) {
164 v->v_type = V_STR;
165 v->v_str = token_str;
166 } else
167 str_free(token_str);
168 (void) s_gettok();
169 break;
170 case T_LP:
171 (void) s_gettok();
172 if (p_expr(v, flag) < 0) {
173 p_synerror();
174 return -1;
176 if (token != T_RP) {
177 p_synerror();
178 val_free(*v);
179 return -1;
181 (void) s_gettok();
182 break;
183 default:
184 return -1;
186 while (token == T_LP) {
187 char *cmd;
189 if (p_convstr(v) < 0)
190 return -1;
191 cmd = v->v_type == V_STR ? v->v_str : 0;
192 if (p_function(cmd, v, flag) < 0) {
193 if (cmd)
194 str_free(cmd);
195 return -1;
197 if (cmd)
198 str_free(cmd);
200 return 0;