xref: /csrg-svn/usr.bin/window/parser5.c (revision 62461)
118754Sedward /*
2*62461Sbostic  * Copyright (c) 1983, 1993
3*62461Sbostic  *	The Regents of the University of California.  All rights reserved.
433514Sbostic  *
542954Sbostic  * This code is derived from software contributed to Berkeley by
642954Sbostic  * Edward Wang at The University of California, Berkeley.
742954Sbostic  *
842835Sbostic  * %sccs.include.redist.c%
918754Sedward  */
1018754Sedward 
1133514Sbostic #ifndef lint
12*62461Sbostic static char sccsid[] = "@(#)parser5.c	8.1 (Berkeley) 06/06/93";
1333514Sbostic #endif /* not lint */
1433514Sbostic 
1515853Sedward #include "parser.h"
1615864Sedward #include "var.h"
1715853Sedward 
1815853Sedward /*
1916714Sedward  * unary $ $? + - ! ~
2015853Sedward  */
p_expr11(v,flag)2115853Sedward p_expr11(v, flag)
2215853Sedward register struct value *v;
2315853Sedward char flag;
2415853Sedward {
2515853Sedward 	int op;
2615853Sedward 	char *opname;
2715853Sedward 
2815853Sedward 	switch (token) {
2915853Sedward 	case T_DOLLAR:
3015853Sedward 		opname = "$";
3115853Sedward 		break;
3216714Sedward 	case T_DQ:
3316714Sedward 		opname = "$?";
3416714Sedward 		break;
3515853Sedward 	case T_PLUS:
3615853Sedward 		opname = "unary +";
3715853Sedward 		break;
3815853Sedward 	case T_MINUS:
3915853Sedward 		opname = "unary -";
4015853Sedward 		break;
4115853Sedward 	case T_NOT:
4215853Sedward 		opname = "!";
4315853Sedward 		break;
4415853Sedward 	case T_COMP:
4515853Sedward 		opname = "~";
4615853Sedward 		break;
4715853Sedward 	default:
4815853Sedward 		return p_expr12(v, flag);
4915853Sedward 	}
5015853Sedward 	op = token;
5115853Sedward 	(void) s_gettok();
5215853Sedward 	if (p_expr11(v, flag) < 0)
5315853Sedward 		return -1;
5415853Sedward 	switch (v->v_type) {
5515853Sedward 	case V_NUM:
5615853Sedward 		break;
5715853Sedward 	case V_STR:
5815853Sedward 		switch (op) {
5915853Sedward 		case T_MINUS:
6015853Sedward 		case T_NOT:
6115853Sedward 		case T_COMP:
6216714Sedward 			p_error("%s: Numeric operand required.", opname);
6315853Sedward 			str_free(v->v_str);
6415853Sedward 			v->v_type = V_ERR;
6515853Sedward 			return 0;
6615853Sedward 		}
6715853Sedward 		break;
6815853Sedward 	case V_ERR:
6915853Sedward 		return 0;
7015853Sedward 	}
7115853Sedward 	switch (op) {
7216714Sedward 	case T_DOLLAR:
7316714Sedward 	case T_DQ:
7416449Sedward 		if (v->v_type == V_NUM) {
7516714Sedward 			int tmp = cx.x_type == X_BUF && cx.x_arg != 0 &&
7616714Sedward 				v->v_num > 0 && v->v_num <= cx.x_narg;
7716714Sedward 			if (op == T_DQ)
7816714Sedward 				v->v_num = tmp;
7916714Sedward 			else if (tmp)
8016714Sedward 				*v = cx.x_arg[v->v_num - 1];
8116714Sedward 			else {
8216449Sedward 				p_error("%d: No such argument.", v->v_num);
8316449Sedward 				v->v_type = V_ERR;
8416449Sedward 			}
8516449Sedward 		} else {
8616714Sedward 			char *name = v->v_str;
8716714Sedward 			struct var *r = var_lookup(name);
8816714Sedward 			if (op == T_DQ) {
8916714Sedward 				v->v_type = V_NUM;
9016714Sedward 				v->v_num = r != 0;
9116714Sedward 			} else if (r != 0)
9216714Sedward 				*v = r->r_val;
9316714Sedward 			else {
9416714Sedward 				p_error("%s: Undefined variable.", name);
9516449Sedward 				v->v_type = V_ERR;
9616449Sedward 			}
9716714Sedward 			str_free(name);
9815853Sedward 		}
9916714Sedward 		if (v->v_type == V_STR && (v->v_str = str_cpy(v->v_str)) == 0) {
10016449Sedward 			p_memerror();
10116449Sedward 			return -1;
10215853Sedward 		}
10315853Sedward 		break;
10415853Sedward 	case T_MINUS:
10515853Sedward 		v->v_num = - v->v_num;
10615853Sedward 		break;
10715853Sedward 	case T_NOT:
10815853Sedward 		v->v_num = ! v->v_num;
10915853Sedward 		break;
11015853Sedward 	case T_COMP:
11115853Sedward 		v->v_num = ~ v->v_num;
11215853Sedward 		break;
11315853Sedward 	}
11415853Sedward 	return 0;
11515853Sedward }
11615853Sedward 
11715853Sedward /*
11815853Sedward  * string, number, ( expr )
11915853Sedward  * Plus function calls.
12015853Sedward  *
12115853Sedward  * Always return v_type == V_ERR when flag == 0.
12215853Sedward  */
p_expr12(v,flag)12315853Sedward p_expr12(v, flag)
12415853Sedward register struct value *v;
12515853Sedward char flag;
12615853Sedward {
12715853Sedward 	v->v_type = V_ERR;
12815853Sedward 	switch (token) {
12915853Sedward 	case T_NUM:
13015853Sedward 		if (flag) {
13115853Sedward 			v->v_type = V_NUM;
13215853Sedward 			v->v_num = token_num;
13315853Sedward 		}
13415853Sedward 		(void) s_gettok();
13515853Sedward 		break;
13615853Sedward 	case T_STR:
13715853Sedward 		if (flag) {
13815853Sedward 			v->v_type = V_STR;
13915853Sedward 			v->v_str = token_str;
14015853Sedward 		} else
14115853Sedward 			str_free(token_str);
14215853Sedward 		(void) s_gettok();
14315853Sedward 		break;
14415853Sedward 	case T_LP:
14515853Sedward 		(void) s_gettok();
14615853Sedward 		if (p_expr(v, flag) < 0) {
14715853Sedward 			p_synerror();
14815853Sedward 			return -1;
14915853Sedward 		}
15015853Sedward 		if (token != T_RP) {
15115853Sedward 			p_synerror();
15215853Sedward 			val_free(*v);
15315853Sedward 			return -1;
15415853Sedward 		}
15515853Sedward 		(void) s_gettok();
15615853Sedward 		break;
15715853Sedward 	default:
15815853Sedward 		return -1;
15915853Sedward 	}
16015853Sedward 	while (token == T_LP) {
16115853Sedward 		char *cmd;
16215853Sedward 
16316449Sedward 		if (p_convstr(v) < 0)
16416449Sedward 			return -1;
16516449Sedward 		cmd = v->v_type == V_STR ? v->v_str : 0;
16615853Sedward 		if (p_function(cmd, v, flag) < 0) {
16716298Sedward 			if (cmd)
16816298Sedward 				str_free(cmd);
16915853Sedward 			return -1;
17015853Sedward 		}
17116298Sedward 		if (cmd)
17216298Sedward 			str_free(cmd);
17315853Sedward 	}
17415853Sedward 	return 0;
17515853Sedward }
176