Fix memory leaks.
[pspp-builds.git] / src / vars-prs.c
index d5001b2dd71c37d5b97eaf51d3ebbc8ce6d2f301..91376a5a68eccd08c74270fa0d1e10b189a65679 100644 (file)
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
    02111-1307, USA. */
 
-/* AIX requires this to be the first thing in the file.  */
 #include <config.h>
-#if __GNUC__
-#define alloca __builtin_alloca
-#else
-#if HAVE_ALLOCA_H
-#include <alloca.h>
-#else
-#ifdef _AIX
-#pragma alloca
-#else
-#ifndef alloca                 /* predefined by HP cc +Olibcalls */
-char *alloca ();
-#endif
-#endif
-#endif
-#endif
-
 #include "var.h"
-#include <assert.h>
 #include <ctype.h>
 #include <stdlib.h>
 #include "alloc.h"
@@ -47,8 +29,11 @@ char *alloca ();
 #include "misc.h"
 #include "str.h"
 
+/* Parses a name as a variable within VS and returns the variable
+   if successful.  On failure emits an error message and returns
+   a null pointer. */
 static struct variable *
-parse_vs_variable (struct var_set *vs)
+parse_vs_variable (const struct var_set *vs)
 {
   struct variable *vp;
 
@@ -66,8 +51,11 @@ parse_vs_variable (struct var_set *vs)
   return vp;
 }
 
+/* Parses a variable name in dictionary D and returns the
+   variable if successful.  On failure emits an error message and
+   returns a null pointer. */
 struct variable *
-parse_dict_variable (struct dictionary *d) 
+parse_dict_variable (const struct dictionary *d) 
 {
   struct var_set *vs = var_set_create_from_dict (d);
   struct variable *var = parse_vs_variable (vs);
@@ -75,13 +63,17 @@ parse_dict_variable (struct dictionary *d)
   return var;
 }
 
+/* Parses a variable name in default_dict and returns the
+   variable if successful.  On failure emits an error message and
+   returns a null pointer. */
 struct variable *
 parse_variable (void)
 {
   return parse_dict_variable (default_dict);
 }
 
-
+/* Returns the dictionary class corresponding to a variable named
+   NAME. */
 enum dict_class
 dict_class_from_id (const char *name) 
 {
@@ -98,25 +90,31 @@ dict_class_from_id (const char *name)
     }
 }
 
+/* Returns the name of dictionary class DICT_CLASS. */
 const char *
 dict_class_to_name (enum dict_class dict_class) 
 {
   switch (dict_class) 
     {
     case DC_ORDINARY:
-      return "ordinary";
+      return _("ordinary");
     case DC_SYSTEM:
-      return "system";
+      return _("system");
     case DC_SCRATCH:
-      return "scratch";
+      return _("scratch");
     default:
       assert (0);
+      abort ();
     }
 }
 
+/* Parses a set of variables from dictionary D given options
+   OPTS.  Resulting list of variables stored in *VAR and the
+   number of variables into *CNT.  Returns nonzero only if
+   successful. */
 int
-parse_variables (struct dictionary *d, struct variable ***var, int *cnt,
-                 int opts) 
+parse_variables (const struct dictionary *d, struct variable ***var,
+                 int *cnt, int opts) 
 {
   struct var_set *vs;
   int success;
@@ -135,13 +133,13 @@ parse_variables (struct dictionary *d, struct variable ***var, int *cnt,
    Conversely, if parse_variables() returns non-zero, then *nv is
    nonzero and *v is non-NULL. */
 int
-parse_var_set_vars (struct var_set *vs, 
+parse_var_set_vars (const struct var_set *vs, 
                     struct variable ***v, int *nv,
                     int pv_opts)
 {
   size_t vs_var_cnt;
   int i;
-  char *included;
+  char *included = NULL;
 
   struct variable *v1, *v2;
   int count, mv;
@@ -314,6 +312,9 @@ fail:
   return 0;
 }
 
+/* Extracts a numeric suffix from variable name S, copying it
+   into string R.  Sets *D to the length of R and *N to its
+   value. */
 static int
 extract_num (char *s, char *r, int *n, int *d)
 {
@@ -392,7 +393,8 @@ parse_DATA_LIST_vars (char ***names, int *nnames, int pv_opts)
          lex_error ("expecting variable name");
          goto fail;
        }
-      if (tokid[0] == '#' && (pv_opts & PV_NO_SCRATCH))
+      if (dict_class_from_id (tokid) == DC_SCRATCH
+          && (pv_opts & PV_NO_SCRATCH))
        {
          msg (SE, _("Scratch variables not allowed here."));
          goto fail;
@@ -519,25 +521,29 @@ fail:
   return 0;
 }
 \f
+/* A set of variables. */
 struct var_set 
   {
-    size_t (*get_cnt) (struct var_set *);
-    struct variable *(*get_var) (struct var_set *, size_t idx);
-    struct variable *(*lookup_var) (struct var_set *, const char *);
+    size_t (*get_cnt) (const struct var_set *);
+    struct variable *(*get_var) (const struct var_set *, size_t idx);
+    struct variable *(*lookup_var) (const struct var_set *, const char *);
     void (*destroy) (struct var_set *);
     void *aux;
   };
 
+/* Returns the number of variables in VS. */
 size_t
-var_set_get_cnt (struct var_set *vs) 
+var_set_get_cnt (const struct var_set *vs) 
 {
   assert (vs != NULL);
 
   return vs->get_cnt (vs);
 }
 
+/* Return variable with index IDX in VS.
+   IDX must be less than the number of variables in VS. */
 struct variable *
-var_set_get_var (struct var_set *vs, size_t idx) 
+var_set_get_var (const struct var_set *vs, size_t idx) 
 {
   assert (vs != NULL);
   assert (idx < var_set_get_cnt (vs));
@@ -545,8 +551,10 @@ var_set_get_var (struct var_set *vs, size_t idx)
   return vs->get_var (vs, idx);
 }
 
+/* Returns the variable in VS named NAME, or a null pointer if VS
+   contains no variable with that name. */
 struct variable *
-var_set_lookup_var (struct var_set *vs, const char *name) 
+var_set_lookup_var (const struct var_set *vs, const char *name) 
 {
   assert (vs != NULL);
   assert (name != NULL);
@@ -555,6 +563,7 @@ var_set_lookup_var (struct var_set *vs, const char *name)
   return vs->lookup_var (vs, name);
 }
 
+/* Destroys VS. */
 void
 var_set_destroy (struct var_set *vs) 
 {
@@ -562,73 +571,86 @@ var_set_destroy (struct var_set *vs)
     vs->destroy (vs);
 }
 \f
+/* Returns the number of variables in VS. */
 static size_t
-dict_var_set_get_cnt (struct var_set *vs) 
+dict_var_set_get_cnt (const struct var_set *vs) 
 {
   struct dictionary *d = vs->aux;
 
   return dict_get_var_cnt (d);
 }
 
+/* Return variable with index IDX in VS.
+   IDX must be less than the number of variables in VS. */
 static struct variable *
-dict_var_set_get_var (struct var_set *vs, size_t idx) 
+dict_var_set_get_var (const struct var_set *vs, size_t idx) 
 {
   struct dictionary *d = vs->aux;
 
   return dict_get_var (d, idx);
 }
 
+/* Returns the variable in VS named NAME, or a null pointer if VS
+   contains no variable with that name. */
 static struct variable *
-dict_var_set_lookup_var (struct var_set *vs, const char *name) 
+dict_var_set_lookup_var (const struct var_set *vs, const char *name) 
 {
   struct dictionary *d = vs->aux;
 
   return dict_lookup_var (d, name);
 }
 
+/* Destroys VS. */
 static void
 dict_var_set_destroy (struct var_set *vs) 
 {
   free (vs);
 }
 
+/* Returns a variable set based on D. */
 struct var_set *
-var_set_create_from_dict (struct dictionary *d) 
+var_set_create_from_dict (const struct dictionary *d) 
 {
   struct var_set *vs = xmalloc (sizeof *vs);
   vs->get_cnt = dict_var_set_get_cnt;
   vs->get_var = dict_var_set_get_var;
   vs->lookup_var = dict_var_set_lookup_var;
   vs->destroy = dict_var_set_destroy;
-  vs->aux = d;
+  vs->aux = (void *) d;
   return vs;
 }
 \f
+/* A variable set based on an array. */
 struct array_var_set 
   {
-    struct variable **var;
-    size_t var_cnt;
-    struct hsh_table *name_tab;
+    struct variable *const *var;/* Array of variables. */
+    size_t var_cnt;             /* Number of elements in var. */
+    struct hsh_table *name_tab; /* Hash from variable names to variables. */
   };
 
+/* Returns the number of variables in VS. */
 static size_t
-array_var_set_get_cnt (struct var_set *vs) 
+array_var_set_get_cnt (const struct var_set *vs) 
 {
   struct array_var_set *avs = vs->aux;
 
   return avs->var_cnt;
 }
 
+/* Return variable with index IDX in VS.
+   IDX must be less than the number of variables in VS. */
 static struct variable *
-array_var_set_get_var (struct var_set *vs, size_t idx) 
+array_var_set_get_var (const struct var_set *vs, size_t idx) 
 {
   struct array_var_set *avs = vs->aux;
 
-  return avs->var[idx];
+  return (struct variable *) avs->var[idx];
 }
 
+/* Returns the variable in VS named NAME, or a null pointer if VS
+   contains no variable with that name. */
 static struct variable *
-array_var_set_lookup_var (struct var_set *vs, const char *name) 
+array_var_set_lookup_var (const struct var_set *vs, const char *name) 
 {
   struct array_var_set *avs = vs->aux;
   struct variable v;
@@ -638,6 +660,7 @@ array_var_set_lookup_var (struct var_set *vs, const char *name)
   return hsh_find (avs->name_tab, &v);
 }
 
+/* Destroys VS. */
 static void
 array_var_set_destroy (struct var_set *vs) 
 {
@@ -648,8 +671,10 @@ array_var_set_destroy (struct var_set *vs)
   free (vs);
 }
 
+/* Returns a variable set based on the VAR_CNT variables in
+   VAR. */
 struct var_set *
-var_set_create_from_array (struct variable **var, size_t var_cnt) 
+var_set_create_from_array (struct variable *const *var, size_t var_cnt) 
 {
   struct var_set *vs;
   struct array_var_set *avs;
@@ -667,7 +692,7 @@ var_set_create_from_array (struct variable **var, size_t var_cnt)
                               compare_variables, hash_variable, NULL,
                               NULL);
   for (i = 0; i < var_cnt; i++)
-    if (hsh_insert (avs->name_tab, var[i]) != NULL) 
+    if (hsh_insert (avs->name_tab, (void *) var[i]) != NULL) 
       {
         var_set_destroy (vs);
         return NULL;