SHOW: Implement SHOW ENVIRONMENT.
[pspp] / src / language / expressions / parse.c
index d06d633d5b02fa4eb40273a02e2d7bbb64e90714..72d706cc794bda1c23016ae43c5565ce3ec04076 100644 (file)
@@ -125,11 +125,13 @@ expr_parse_bool (struct lexer *lexer, struct dataset *ds)
 }
 
 /* Parses a numeric expression that is intended to be assigned to newly created
-   variable NEW_VAR_NAME.  (This allows for a better error message if the
-   expression is not numeric.)  Otherwise similar to expr_parse(). */
+   variable NEW_VAR_NAME at NEW_VAR_LOCATION.  (This allows for a better error
+   message if the expression is not numeric.)  Otherwise similar to
+   expr_parse(). */
 struct expression *
 expr_parse_new_variable (struct lexer *lexer, struct dataset *ds,
-                         const char *new_var_name)
+                         const char *new_var_name,
+                         const struct msg_location *new_var_location)
 {
   struct expression *e = expr_create (ds);
   struct expr_node *n = parse_expr (lexer, e);
@@ -142,10 +144,11 @@ expr_parse_new_variable (struct lexer *lexer, struct dataset *ds,
   atom_type actual_type = expr_node_returns (n);
   if (actual_type != OP_number && actual_type != OP_boolean)
     {
-      msg (SE, _("This command tries to create a new variable %s by assigning a "
-                 "string value to it, but this is not supported.  Use "
-                 "the STRING command to create the new variable with the "
-                 "correct width before assigning to it, e.g. STRING %s(A20)."),
+      msg_at (SE, new_var_location,
+              _("This command tries to create a new variable %s by assigning a "
+                "string value to it, but this is not supported.  Use "
+                "the STRING command to create the new variable with the "
+                "correct width before assigning to it, e.g. STRING %s(A20)."),
            new_var_name, new_var_name);
       expr_free (e);
       return NULL;
@@ -487,31 +490,25 @@ type_coercion__ (struct expression *e, struct expr_node *node, size_t arg_idx,
       NOT_REACHED ();
 
     case OP_ni_format:
-      msg_disable ();
       if (arg->type == OP_format
-          && fmt_check_input (&arg->format)
-          && fmt_check_type_compat (&arg->format, VAL_NUMERIC))
+          && fmt_check_input (arg->format)
+          && fmt_check_type_compat (arg->format, VAL_NUMERIC))
         {
-          msg_enable ();
           if (do_coercion)
             arg->type = OP_ni_format;
           return true;
         }
-      msg_enable ();
       break;
 
     case OP_no_format:
-      msg_disable ();
       if (arg->type == OP_format
-          && fmt_check_output (&arg->format)
-          && fmt_check_type_compat (&arg->format, VAL_NUMERIC))
+          && fmt_check_output (arg->format)
+          && fmt_check_type_compat (arg->format, VAL_NUMERIC))
         {
-          msg_enable ();
           if (do_coercion)
             arg->type = OP_no_format;
           return true;
         }
-      msg_enable ();
       break;
 
     case OP_num_var:
@@ -863,9 +860,7 @@ expr_date (struct expression *e, int year_digits)
                : xasprintf ("%02d-%s-%04d", time->tm_mday, months[time->tm_mon],
                             time->tm_year + 1900));
 
-  struct substring s;
-  ss_alloc_substring_pool (&s, ss_cstr (tmp), e->expr_pool);
-
+  struct substring s = ss_clone_pool (ss_cstr (tmp), e->expr_pool);
   free (tmp);
 
   return expr_allocate_string (e, s);
@@ -912,7 +907,7 @@ parse_sysvar (struct lexer *lexer, struct expression *e)
     return expr_allocate_number (e, settings_get_viewwidth ());
   else
     {
-      msg (SE, _("Unknown system variable %s."), lex_tokcstr (lexer));
+      lex_error (lexer, _("Unknown system variable %s."), lex_tokcstr (lexer));
       return NULL;
     }
 }
@@ -957,10 +952,10 @@ parse_primary__ (struct lexer *lexer, struct expression *e)
           msg_enable ();
 
           if (ok)
-            return expr_allocate_format (e, &fmt);
+            return expr_allocate_format (e, fmt);
 
           /* All attempts failed. */
-          msg (SE, _("Unknown identifier %s."), lex_tokcstr (lexer));
+          lex_error (lexer, _("Unknown identifier %s."), lex_tokcstr (lexer));
           return NULL;
         }
       break;
@@ -998,7 +993,7 @@ parse_primary__ (struct lexer *lexer, struct expression *e)
       }
 
     default:
-      lex_error (lexer, NULL);
+      lex_error (lexer, _("Syntax error parsing expression."));
       return NULL;
     }
 }
@@ -1300,11 +1295,11 @@ no_match (struct expression *e, const char *func_name, struct expr_node *node,
             if ((expected == OP_ni_format || expected == OP_no_format)
                 && actual == OP_format)
               {
-                const struct fmt_spec *f = &node->args[i]->format;
+                struct fmt_spec f = node->args[i]->format;
                 char *error = fmt_check__ (f, (ops->args[i] == OP_ni_format
                                                ? FMT_FOR_INPUT : FMT_FOR_OUTPUT));
                 if (!error)
-                  error = fmt_check_type_compat__ (f, VAL_NUMERIC);
+                  error = fmt_check_type_compat__ (f, NULL, VAL_NUMERIC);
                 if (error)
                   {
                     msg_at (SN, expr_location (e, node->args[i]), "%s", error);
@@ -1332,7 +1327,8 @@ parse_function (struct lexer *lexer, struct expression *e)
   const struct operation *first, *last;
   if (!lookup_function (lex_tokcstr (lexer), &first, &last))
     {
-      msg (SE, _("No function or vector named %s."), lex_tokcstr (lexer));
+      lex_error (lexer, _("No function or vector named %s."),
+                 lex_tokcstr (lexer));
       ds_destroy (&func_name);
       return NULL;
     }
@@ -1586,10 +1582,10 @@ expr_allocate_variable (struct expression *e, const struct variable *v)
 }
 
 struct expr_node *
-expr_allocate_format (struct expression *e, const struct fmt_spec *format)
+expr_allocate_format (struct expression *e, struct fmt_spec format)
 {
   struct expr_node *n = pool_alloc (e->expr_pool, sizeof *n);
-  *n = (struct expr_node) { .type = OP_format, .format = *format };
+  *n = (struct expr_node) { .type = OP_format, .format = format };
   return n;
 }