Completely rewrite src/data/format.[ch], to achieve better
[pspp-builds.git] / src / data / dictionary.c
index e9a5a01450363bbdc8055abf7a760731de12facf..ebe6a5e5d100b829f22e5943c12c0027755ebb59 100644 (file)
@@ -281,20 +281,20 @@ dict_create_var (struct dictionary *d, const char *name, int width)
   v->type = width == 0 ? NUMERIC : ALPHA;
   v->width = width;
   v->fv = d->next_value_idx;
-  v->nv = width_to_bytes(width) / MAX_SHORT_STRING ;
+  v->nv = width == 0 ? 1 : DIV_RND_UP (width, MAX_SHORT_STRING);
   v->leave = dict_class_from_id (v->name) == DC_SCRATCH;
   v->index = d->var_cnt;
   mv_init (&v->miss, width);
   if (v->type == NUMERIC)
     {
-      v->print = f8_2;
+      v->print = fmt_for_output (FMT_F, 8, 2);
       v->alignment = ALIGN_RIGHT;
       v->display_width = 8;
       v->measure = MEASURE_SCALE;
     }
   else
     {
-      v->print = make_output_format (FMT_A, v->width, 0);
+      v->print = fmt_for_output (FMT_A, v->width, 0);
       v->alignment = ALIGN_LEFT;
       v->display_width = 8;
       v->measure = MEASURE_NOMINAL;
@@ -424,7 +424,7 @@ dict_contains_var (const struct dictionary *d, const struct variable *v)
 /* Compares two double pointers to variables, which should point
    to elements of a struct dictionary's `var' member array. */
 static int
-compare_var_ptrs (const void *a_, const void *b_, void *aux UNUSED) 
+compare_var_ptrs (const void *a_, const void *b_, const void *aux UNUSED) 
 {
   struct variable *const *a = a_;
   struct variable *const *b = b_;
@@ -435,8 +435,8 @@ compare_var_ptrs (const void *a_, const void *b_, void *aux UNUSED)
 /* Deletes variable V from dictionary D and frees V.
 
    This is a very bad idea if there might be any pointers to V
-   from outside D.  In general, no variable in default_dict
-   should be deleted when any transformations are active, because
+   from outside D.  In general, no variable in should be deleted when 
+   any transformations are active on the dictionary's dataset, because
    those transformations might reference the deleted variable.
    The safest time to delete a variable is just after a procedure
    has been executed, as done by MODIFY VARS.
@@ -687,11 +687,11 @@ dict_get_weight (const struct dictionary *d)
 /* Returns the value of D's weighting variable in case C, except that a
    negative weight is returned as 0.  Returns 1 if the dictionary is
    unweighted. Will warn about missing, negative, or zero values if
-   warn_on_invalid is nonzero. The function will set warn_on_invalid to zero
+   warn_on_invalid is true. The function will set warn_on_invalid to false
    if an invalid weight is found. */
 double
 dict_get_case_weight (const struct dictionary *d, const struct ccase *c, 
-                     int *warn_on_invalid)
+                     bool *warn_on_invalid)
 {
   assert (d != NULL);
   assert (c != NULL);
@@ -704,7 +704,7 @@ dict_get_case_weight (const struct dictionary *d, const struct ccase *c,
       if (w < 0.0 || mv_is_num_missing (&d->weight->miss, w))
         w = 0.0;
       if ( w == 0.0 && *warn_on_invalid ) {
-         *warn_on_invalid = 0;
+         *warn_on_invalid = false;
          msg (SW, _("At least one case in the data file had a weight value "
                     "that was user-missing, system-missing, zero, or "
                     "negative.  These case(s) were ignored."));
@@ -855,19 +855,44 @@ dict_get_compacted_idx_to_fv (const struct dictionary *d)
 }
 
 /* Returns true if a case for dictionary D would be smaller after
-   compaction, false otherwise.  Compacting a case eliminates
+   compacting, false otherwise.  Compacting a case eliminates
    "holes" between values and after the last value.  Holes are
    created by deleting variables (or by scratch variables).
 
    The return value may differ from whether compacting a case
-   from dictionary D would *change* the case: compaction could
+   from dictionary D would *change* the case: compacting could
    rearrange values even if it didn't reduce space
    requirements. */
 bool
-dict_needs_compaction (const struct dictionary *d) 
+dict_compacting_would_shrink (const struct dictionary *d) 
 {
   return dict_get_compacted_value_cnt (d) < dict_get_next_value_idx (d);
 }
+
+/* Returns true if a case for dictionary D would change after
+   compacting, false otherwise.  Compacting a case eliminates
+   "holes" between values and after the last value.  Holes are
+   created by deleting variables (or by scratch variables).
+
+   The return value may differ from whether compacting a case
+   from dictionary D would *shrink* the case: compacting could
+   rearrange values without reducing space requirements. */
+bool
+dict_compacting_would_change (const struct dictionary *d) 
+{
+  size_t case_idx;
+  size_t i;
+
+  case_idx = 0;
+  for (i = 0; i < dict_get_var_cnt (d); i++) 
+    {
+      struct variable *v = dict_get_var (d, i);
+      if (v->fv != case_idx)
+        return true;
+      case_idx += v->nv;
+    }
+  return false;
+}
 \f
 /* How to copy a contiguous range of values between cases. */
 struct copy_map
@@ -1139,14 +1164,14 @@ dict_clear_vectors (struct dictionary *d)
 
 /* Compares two strings. */
 static int
-compare_strings (const void *a, const void *b, void *aux UNUSED) 
+compare_strings (const void *a, const void *b, const void *aux UNUSED) 
 {
   return strcmp (a, b);
 }
 
 /* Hashes a string. */
 static unsigned
-hash_string (const void *s, void *aux UNUSED) 
+hash_string (const void *s, const void *aux UNUSED) 
 {
   return hsh_hash_string (s);
 }