xref: /csrg-svn/usr.bin/window/parser5.c (revision 33514)
118754Sedward /*
2*33514Sbostic  * Copyright (c) 1983 Regents of the University of California.
3*33514Sbostic  * All rights reserved.
4*33514Sbostic  *
5*33514Sbostic  * Redistribution and use in source and binary forms are permitted
6*33514Sbostic  * provided that this notice is preserved and that due credit is given
7*33514Sbostic  * to the University of California at Berkeley. The name of the University
8*33514Sbostic  * may not be used to endorse or promote products derived from this
9*33514Sbostic  * software without specific prior written permission. This software
10*33514Sbostic  * is provided ``as is'' without express or implied warranty.
1118754Sedward  */
1218754Sedward 
13*33514Sbostic #ifndef lint
14*33514Sbostic static char sccsid[] = "@(#)parser5.c	3.10 (Berkeley) 02/21/88";
15*33514Sbostic #endif /* not lint */
16*33514Sbostic 
1715853Sedward #include "parser.h"
1815864Sedward #include "var.h"
1915853Sedward 
2015853Sedward /*
2116714Sedward  * unary $ $? + - ! ~
2215853Sedward  */
2315853Sedward p_expr11(v, flag)
2415853Sedward register struct value *v;
2515853Sedward char flag;
2615853Sedward {
2715853Sedward 	int op;
2815853Sedward 	char *opname;
2915853Sedward 
3015853Sedward 	switch (token) {
3115853Sedward 	case T_DOLLAR:
3215853Sedward 		opname = "$";
3315853Sedward 		break;
3416714Sedward 	case T_DQ:
3516714Sedward 		opname = "$?";
3616714Sedward 		break;
3715853Sedward 	case T_PLUS:
3815853Sedward 		opname = "unary +";
3915853Sedward 		break;
4015853Sedward 	case T_MINUS:
4115853Sedward 		opname = "unary -";
4215853Sedward 		break;
4315853Sedward 	case T_NOT:
4415853Sedward 		opname = "!";
4515853Sedward 		break;
4615853Sedward 	case T_COMP:
4715853Sedward 		opname = "~";
4815853Sedward 		break;
4915853Sedward 	default:
5015853Sedward 		return p_expr12(v, flag);
5115853Sedward 	}
5215853Sedward 	op = token;
5315853Sedward 	(void) s_gettok();
5415853Sedward 	if (p_expr11(v, flag) < 0)
5515853Sedward 		return -1;
5615853Sedward 	switch (v->v_type) {
5715853Sedward 	case V_NUM:
5815853Sedward 		break;
5915853Sedward 	case V_STR:
6015853Sedward 		switch (op) {
6115853Sedward 		case T_MINUS:
6215853Sedward 		case T_NOT:
6315853Sedward 		case T_COMP:
6416714Sedward 			p_error("%s: Numeric operand required.", opname);
6515853Sedward 			str_free(v->v_str);
6615853Sedward 			v->v_type = V_ERR;
6715853Sedward 			return 0;
6815853Sedward 		}
6915853Sedward 		break;
7015853Sedward 	case V_ERR:
7115853Sedward 		return 0;
7215853Sedward 	}
7315853Sedward 	switch (op) {
7416714Sedward 	case T_DOLLAR:
7516714Sedward 	case T_DQ:
7616449Sedward 		if (v->v_type == V_NUM) {
7716714Sedward 			int tmp = cx.x_type == X_BUF && cx.x_arg != 0 &&
7816714Sedward 				v->v_num > 0 && v->v_num <= cx.x_narg;
7916714Sedward 			if (op == T_DQ)
8016714Sedward 				v->v_num = tmp;
8116714Sedward 			else if (tmp)
8216714Sedward 				*v = cx.x_arg[v->v_num - 1];
8316714Sedward 			else {
8416449Sedward 				p_error("%d: No such argument.", v->v_num);
8516449Sedward 				v->v_type = V_ERR;
8616449Sedward 			}
8716449Sedward 		} else {
8816714Sedward 			char *name = v->v_str;
8916714Sedward 			struct var *r = var_lookup(name);
9016714Sedward 			if (op == T_DQ) {
9116714Sedward 				v->v_type = V_NUM;
9216714Sedward 				v->v_num = r != 0;
9316714Sedward 			} else if (r != 0)
9416714Sedward 				*v = r->r_val;
9516714Sedward 			else {
9616714Sedward 				p_error("%s: Undefined variable.", name);
9716449Sedward 				v->v_type = V_ERR;
9816449Sedward 			}
9916714Sedward 			str_free(name);
10015853Sedward 		}
10116714Sedward 		if (v->v_type == V_STR && (v->v_str = str_cpy(v->v_str)) == 0) {
10216449Sedward 			p_memerror();
10316449Sedward 			return -1;
10415853Sedward 		}
10515853Sedward 		break;
10615853Sedward 	case T_MINUS:
10715853Sedward 		v->v_num = - v->v_num;
10815853Sedward 		break;
10915853Sedward 	case T_NOT:
11015853Sedward 		v->v_num = ! v->v_num;
11115853Sedward 		break;
11215853Sedward 	case T_COMP:
11315853Sedward 		v->v_num = ~ v->v_num;
11415853Sedward 		break;
11515853Sedward 	}
11615853Sedward 	return 0;
11715853Sedward }
11815853Sedward 
11915853Sedward /*
12015853Sedward  * string, number, ( expr )
12115853Sedward  * Plus function calls.
12215853Sedward  *
12315853Sedward  * Always return v_type == V_ERR when flag == 0.
12415853Sedward  */
12515853Sedward p_expr12(v, flag)
12615853Sedward register struct value *v;
12715853Sedward char flag;
12815853Sedward {
12915853Sedward 	v->v_type = V_ERR;
13015853Sedward 	switch (token) {
13115853Sedward 	case T_NUM:
13215853Sedward 		if (flag) {
13315853Sedward 			v->v_type = V_NUM;
13415853Sedward 			v->v_num = token_num;
13515853Sedward 		}
13615853Sedward 		(void) s_gettok();
13715853Sedward 		break;
13815853Sedward 	case T_STR:
13915853Sedward 		if (flag) {
14015853Sedward 			v->v_type = V_STR;
14115853Sedward 			v->v_str = token_str;
14215853Sedward 		} else
14315853Sedward 			str_free(token_str);
14415853Sedward 		(void) s_gettok();
14515853Sedward 		break;
14615853Sedward 	case T_LP:
14715853Sedward 		(void) s_gettok();
14815853Sedward 		if (p_expr(v, flag) < 0) {
14915853Sedward 			p_synerror();
15015853Sedward 			return -1;
15115853Sedward 		}
15215853Sedward 		if (token != T_RP) {
15315853Sedward 			p_synerror();
15415853Sedward 			val_free(*v);
15515853Sedward 			return -1;
15615853Sedward 		}
15715853Sedward 		(void) s_gettok();
15815853Sedward 		break;
15915853Sedward 	default:
16015853Sedward 		return -1;
16115853Sedward 	}
16215853Sedward 	while (token == T_LP) {
16315853Sedward 		char *cmd;
16415853Sedward 
16516449Sedward 		if (p_convstr(v) < 0)
16616449Sedward 			return -1;
16716449Sedward 		cmd = v->v_type == V_STR ? v->v_str : 0;
16815853Sedward 		if (p_function(cmd, v, flag) < 0) {
16916298Sedward 			if (cmd)
17016298Sedward 				str_free(cmd);
17115853Sedward 			return -1;
17215853Sedward 		}
17316298Sedward 		if (cmd)
17416298Sedward 			str_free(cmd);
17515853Sedward 	}
17615853Sedward 	return 0;
17715853Sedward }
178