work on memory leaks
authorBen Pfaff <blp@cs.stanford.edu>
Thu, 4 Aug 2022 06:29:58 +0000 (23:29 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Thu, 4 Aug 2022 06:29:58 +0000 (23:29 -0700)
src/language/stats/ctables.c

index 4b4d58d8a9add8c1e79a41b909c28449ad8b67ba..dd97afc0cc97e3c56adffc9a643ae60a8e831406 100644 (file)
@@ -615,6 +615,7 @@ ctables_category_uninit (struct ctables_category *cat)
   if (!cat)
     return;
 
+  msg_location_destroy (cat->location);
   switch (cat->type)
     {
     case CCT_NUMBER:
@@ -1554,6 +1555,18 @@ ctables_table_destroy (struct ctables_table *t)
       ctables_stack_uninit (&t->stacks[a]);
     }
 
+  struct ctables_value *ctv, *next_ctv;
+  HMAP_FOR_EACH_SAFE (ctv, next_ctv, struct ctables_value, node,
+                      &t->clabels_values_map)
+    {
+      value_destroy (&ctv->value, var_get_width (t->clabels_example));
+      hmap_delete (&t->clabels_values_map, &ctv->node);
+      free (ctv);
+    }
+  hmap_destroy (&t->clabels_values_map);
+  free (t->clabels_values);
+
+  free (t->sum_vars);
   free (t->caption);
   free (t->corner);
   free (t->title);
@@ -2037,7 +2050,7 @@ ctables_table_parse_categories (struct lexer *lexer, struct dictionary *dict,
           int start_ofs = lex_ofs (lexer);
           struct ctables_category *cat = &c->cats[c->n_cats];
           if (!ctables_table_parse_explicit_category (lexer, dict, ct, cat))
-            return false;
+            goto error;
           cat->location = lex_ofs_location (lexer, start_ofs, lex_ofs (lexer) - 1);
           c->n_cats++;
 
@@ -2067,7 +2080,7 @@ ctables_table_parse_categories (struct lexer *lexer, struct dictionary *dict,
           else
             {
               lex_error_expecting (lexer, "A", "D");
-              return false;
+              goto error;
             }
         }
       else if (!c->n_cats && lex_match_id (lexer, "KEY"))
@@ -2081,31 +2094,31 @@ ctables_table_parse_categories (struct lexer *lexer, struct dictionary *dict,
             {
               cat.type = CCT_FUNCTION;
               if (!parse_ctables_summary_function (lexer, &cat.sort_function))
-                return false;
+                goto error;
 
               if (lex_match (lexer, T_LPAREN))
                 {
                   cat.sort_var = parse_variable (lexer, dict);
                   if (!cat.sort_var)
-                    return false;
+                    goto error;
 
                   if (cat.sort_function == CTSF_PTILE)
                     {
                       lex_match (lexer, T_COMMA);
                       if (!lex_force_num_range_closed (lexer, "PTILE", 0, 100))
-                        return false;
+                        goto error;
                       cat.percentile = lex_number (lexer);
                       lex_get (lexer);
                     }
 
                   if (!lex_force_match (lexer, T_RPAREN))
-                    return false;
+                    goto error;
                 }
               else if (ctables_function_availability (cat.sort_function)
                        == CTFA_SCALE)
                 {
                   bool UNUSED b = lex_force_match (lexer, T_LPAREN);
-                  return false;
+                  goto error;
                 }
             }
         }
@@ -2119,20 +2132,20 @@ ctables_table_parse_categories (struct lexer *lexer, struct dictionary *dict,
           else
             {
               lex_error_expecting (lexer, "INCLUDE", "EXCLUDE");
-              return false;
+              goto error;
             }
         }
       else if (lex_match_id (lexer, "TOTAL"))
         {
           lex_match (lexer, T_EQUALS);
           if (!parse_bool (lexer, &show_totals))
-            return false;
+            goto error;
         }
       else if (lex_match_id (lexer, "LABEL"))
         {
           lex_match (lexer, T_EQUALS);
           if (!lex_force_string (lexer))
-            return false;
+            goto error;
           free (total_label);
           total_label = ss_xstrdup (lex_tokss (lexer));
           lex_get (lexer);
@@ -2147,7 +2160,7 @@ ctables_table_parse_categories (struct lexer *lexer, struct dictionary *dict,
           else
             {
               lex_error_expecting (lexer, "BEFORE", "AFTER");
-              return false;
+              goto error;
             }
         }
       else if (lex_match_id (lexer, "EMPTY"))
@@ -2160,7 +2173,7 @@ ctables_table_parse_categories (struct lexer *lexer, struct dictionary *dict,
           else
             {
               lex_error_expecting (lexer, "INCLUDE", "EXCLUDE");
-              return false;
+              goto error;
             }
         }
       else
@@ -2170,7 +2183,7 @@ ctables_table_parse_categories (struct lexer *lexer, struct dictionary *dict,
                                  "TOTAL", "LABEL", "POSITION", "EMPTY");
           else
             lex_error_expecting (lexer, "TOTAL", "LABEL", "POSITION", "EMPTY");
-          return false;
+          goto error;
         }
     }
 
@@ -2237,8 +2250,6 @@ ctables_table_parse_categories (struct lexer *lexer, struct dictionary *dict,
 
   if (cats_start_ofs != -1)
     {
-      struct msg_location *cats_location
-        = lex_ofs_location (lexer, cats_start_ofs, cats_end_ofs);
       for (size_t i = 0; i < c->n_cats; i++)
         {
           struct ctables_category *cat = &c->cats[i];
@@ -2246,9 +2257,13 @@ ctables_table_parse_categories (struct lexer *lexer, struct dictionary *dict,
             {
             case CCT_POSTCOMPUTE:
               cat->parse_format = parse_strings ? common_format->type : FMT_F;
-              if (!ctables_recursive_check_postcompute (dict, cat->pc->expr,
-                                                        cat, c, cats_location))
-                return false;
+              struct msg_location *cats_location
+                = lex_ofs_location (lexer, cats_start_ofs, cats_end_ofs);
+              bool ok = ctables_recursive_check_postcompute (
+                dict, cat->pc->expr, cat, c, cats_location);
+              msg_location_destroy (cats_location);
+              if (!ok)
+                goto error;
               break;
 
             case CCT_NUMBER:
@@ -2262,7 +2277,7 @@ ctables_table_parse_categories (struct lexer *lexer, struct dictionary *dict,
                               "subcommand tries to apply it to string "
                               "variable %s."),
                             var_get_name (vars[j]));
-                    return false;
+                    goto error;
                   }
               break;
 
@@ -2272,7 +2287,7 @@ ctables_table_parse_categories (struct lexer *lexer, struct dictionary *dict,
                   double n;
                   if (!parse_category_string (cat->location, cat->string, dict,
                                               common_format->type, &n))
-                    return false;
+                    goto error;
 
                   ss_dealloc (&cat->string);
 
@@ -2280,7 +2295,7 @@ ctables_table_parse_categories (struct lexer *lexer, struct dictionary *dict,
                   cat->number = n;
                 }
               else if (!all_strings (vars, n_vars, cat))
-                return false;
+                goto error;
               break;
 
             case CCT_SRANGE:
@@ -2293,14 +2308,14 @@ ctables_table_parse_categories (struct lexer *lexer, struct dictionary *dict,
                   else if (!parse_category_string (cat->location,
                                                    cat->srange[0], dict,
                                                    common_format->type, &n[0]))
-                    return false;
+                    goto error;
 
                   if (!cat->srange[1].string)
                     n[1] = DBL_MAX;
                   else if (!parse_category_string (cat->location,
                                                    cat->srange[1], dict,
                                                    common_format->type, &n[1]))
-                    return false;
+                    goto error;
 
                   ss_dealloc (&cat->srange[0]);
                   ss_dealloc (&cat->srange[1]);
@@ -2310,7 +2325,7 @@ ctables_table_parse_categories (struct lexer *lexer, struct dictionary *dict,
                   cat->nrange[1] = n[1];
                 }
               else if (!all_strings (vars, n_vars, cat))
-                return false;
+                goto error;
               break;
 
             case CCT_MISSING:
@@ -2326,7 +2341,12 @@ ctables_table_parse_categories (struct lexer *lexer, struct dictionary *dict,
         }
     }
 
+  free (vars);
   return true;
+
+error:
+  free (vars);
+  return false;
 }
 
 static void