aboutsummaryrefslogtreecommitdiffstats
path: root/awk.y
diff options
context:
space:
mode:
Diffstat (limited to 'awk.y')
-rw-r--r--awk.y55
1 files changed, 49 insertions, 6 deletions
diff --git a/awk.y b/awk.y
index d4b443fa..f855f254 100644
--- a/awk.y
+++ b/awk.y
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-1995 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-1996 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -52,7 +52,8 @@ static NODE *make_param P((char *name));
static NODE *mk_rexp P((NODE *exp));
static int dup_parms P((NODE *func));
static void param_sanity P((NODE *arglist));
-static int isnoeffect P((NODETYPE));
+static int isnoeffect P((NODETYPE t));
+static int isassignable P((NODE *n));
enum defref { FUNC_DEFINE, FUNC_USE };
static void func_use P((char *name, enum defref how));
@@ -279,7 +280,11 @@ function_prologue
}
func_name '(' opt_param_list r_paren opt_nls
{
- $$ = append_right(make_param($3), $5);
+ NODE *t;
+
+ t = make_param($3);
+ t->flags |= FUNC;
+ $$ = append_right(t, $5);
can_return = TRUE;
/* check for duplicate parameter names */
if (dup_parms($$))
@@ -1002,7 +1007,6 @@ va_dcl
strcpy(bp, mesg);
err("", buf, args);
va_end(args);
- exit(2);
}
/* get_src_buf --- read the next buffer of source program */
@@ -1844,6 +1848,11 @@ NODE *subn;
r->proc = tokentab[idx].ptr;
/* special case processing for a few builtins */
+ /*
+ * FIXME: go through these to make sure that everything done
+ * here is really right. Move anything that's not into
+ * the corresponding routine.
+ */
if (nexp == 0 && r->proc == do_length) {
subn = node(node(make_number(0.0), Node_field_spec, (NODE *) NULL),
Node_expression_list,
@@ -1860,8 +1869,12 @@ NODE *subn;
(NODE *) NULL),
Node_expression_list,
(NODE *) NULL));
- else if (do_lint && subn->rnode->rnode->lnode->type == Node_val)
- warning("string literal as last arg of substitute");
+ else if (subn->rnode->rnode->lnode->type == Node_val) {
+ if (do_lint)
+ warning("string literal as last arg of substitute");
+ } else if (! isassignable(subn->rnode->rnode->lnode))
+ yyerror("%s third parameter is not a changeable object",
+ r->proc == do_sub ? "sub" : "gsub");
} else if (r->proc == do_gensub) {
if (subn->lnode->type != Node_regex)
subn->lnode = mk_rexp(subn->lnode);
@@ -2318,3 +2331,33 @@ NODETYPE type;
return FALSE;
}
+
+/* isassignable --- can this node be assigned to? */
+
+static int
+isassignable(n)
+register NODE *n;
+{
+ switch (n->type) {
+ case Node_var:
+ case Node_FIELDWIDTHS:
+ case Node_RS:
+ case Node_FS:
+ case Node_FNR:
+ case Node_NR:
+ case Node_NF:
+ case Node_IGNORECASE:
+ case Node_OFMT:
+ case Node_CONVFMT:
+ case Node_ORS:
+ case Node_OFS:
+ case Node_field_spec:
+ case Node_subscript:
+ return TRUE;
+ case Node_param_list:
+ return ((n->flags & FUNC) == 0); /* ok if not func name */
+ default:
+ break; /* keeps gcc -Wall happy */
+ }
+ return FALSE;
+}