Suppress warnings about conversions between char * and unsigned char *.
authorBen Pfaff <blp@cs.stanford.edu>
Sat, 18 Sep 2010 04:03:57 +0000 (21:03 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sat, 18 Sep 2010 13:51:37 +0000 (06:51 -0700)
For some time PSPP has used "unsigned char *" for string data and "char *"
for most other strings.  Transforming between these properly generally
involves recoding, and there are some places where this is possibly
missing.  The usual way to "fix" these warnings would be to insert casts,
but this would not fix the problem, just suppress the warnings, and it is
difficult to "grep" for casts so they would be hard to find for fixing
later.

This commit doesn't actually fix the problems, but it does suppress the
warnings while making them easy to find later: just grep for CHAR_CAST_BUG.

src/language/expressions/operations.def
src/language/lexer/value-parser.c
src/language/xforms/compute.c
src/language/xforms/recode.c
src/libpspp/cast.h
src/ui/syntax-gen.c

index 844cab7e17ed133393d983bc02e6bf606b96ea4e..c25f113c319c4b214a46c923d2fdceffcf46fc75 100644 (file)
@@ -961,7 +961,8 @@ absorb_miss no_opt string operator VEC_ELEM_STR (idx)
   if (idx >= 1 && idx <= vector_get_var_cnt (v))
     {
       struct variable *var = vector_get_var (v, (size_t) idx - 1);
-      return copy_string (e, case_str (c, var), var_get_width (var));
+      return copy_string (e, CHAR_CAST_BUG (char *, case_str (c, var)),
+                          var_get_width (var));
     }
   else
     {
@@ -1029,7 +1030,8 @@ no_opt perm_only string function LAG (str_var v, pos_int n_before)
 {
   const struct ccase *c = lagged_case (ds, n_before);
   if (c != NULL)
-    return copy_string (e, case_str (c, v), var_get_width (v));
+    return copy_string (e, CHAR_CAST_BUG (char *, case_str (c, v)),
+                        var_get_width (v));
   else
     return empty_string;
 }
@@ -1040,7 +1042,8 @@ no_opt perm_only string function LAG (str_var v)
 {
   const struct ccase *c = lagged_case (ds, 1);
   if (c != NULL)
-    return copy_string (e, case_str (c, v), var_get_width (v));
+    return copy_string (e, CHAR_CAST_BUG (char *, case_str (c, v)),
+                        var_get_width (v));
   else
     return empty_string;
 }
index c780d86f04e95429bad3ee1004bbf2021ab89884..c492658e28753ba5e3a9fe7780abf9a2fc7ba12c 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2005, 2006, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2006, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
 #include <config.h>
+
 #include "value-parser.h"
+
 #include <stdbool.h>
-#include <data/data-in.h>
-#include <libpspp/message.h>
-#include "lexer.h"
-#include <libpspp/str.h>
-#include <data/value.h>
-#include <data/format.h>
+
+#include "data/data-in.h"
+#include "data/format.h"
+#include "data/value.h"
+#include "language/lexer/lexer.h"
+#include "libpspp/cast.h"
+#include "libpspp/message.h"
+#include "libpspp/str.h"
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
@@ -133,12 +137,13 @@ parse_value (struct lexer *lexer, union value *v, int width)
        return false;
       v->f = lex_tokval (lexer);
     }
-  else
+  else if (lex_force_string (lexer))
     {
-      if (!lex_force_string (lexer))
-       return false;
-      value_copy_str_rpad (v, width, ds_cstr (lex_tokstr (lexer)), ' ');
+      const char *s = ds_cstr (lex_tokstr (lexer));
+      value_copy_str_rpad (v, width, CHAR_CAST_BUG (const uint8_t *, s), ' ');
     }
+  else
+    return false;
 
   lex_get (lexer);
 
index 09fc2155abc82c0a678364301b1ea0de6b3fa9c9..a508933c68cb7686d2690ec0d75048662b3b4e18 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -173,10 +173,11 @@ compute_str (void *compute_, struct ccase **c, casenumber case_num)
   if (compute->test == NULL
       || expr_evaluate_num (compute->test, *c, case_num) == 1.0)
     {
+      char *s;
+
       *c = case_unshare (*c);
-      expr_evaluate_str (compute->rvalue, *c, case_num,
-                         case_str_rw (*c, compute->variable),
-                         compute->width);
+      s = CHAR_CAST_BUG (char *, case_str_rw (*c, compute->variable));
+      expr_evaluate_str (compute->rvalue, *c, case_num, s, compute->width);
     }
 
   return TRNS_CONTINUE;
@@ -216,7 +217,8 @@ compute_str_vec (void *compute_, struct ccase **c, casenumber case_num)
       vr = vector_get_var (compute->vector, rindx - 1);
       *c = case_unshare (*c);
       expr_evaluate_str (compute->rvalue, *c, case_num,
-                         case_str_rw (*c, vr), var_get_width (vr));
+                         CHAR_CAST_BUG (char *, case_str_rw (*c, vr)),
+                         var_get_width (vr));
     }
 
   return TRNS_CONTINUE;
index 62b03ba073b9a5f6f6a1c5b282d9c26b0ce286b9..f4a19a9c9e14bb16052fd9f39dbc3b34f8fe56fb 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -373,7 +373,8 @@ set_map_in_str (struct map_in *in, struct pool *pool,
   in->type = MAP_SINGLE;
   value_init_pool (pool, &in->x, width);
   value_copy_buf_rpad (&in->x, width,
-                       ds_data (string), ds_length (string), ' ');
+                       CHAR_CAST_BUG (uint8_t *, ds_data (string)),
+                       ds_length (string), ' ');
 }
 
 /* Parses a mapping output value into OUT, allocating memory from
@@ -629,8 +630,9 @@ find_src_string (struct recode_trns *trns, const uint8_t *value,
             union value uv;
 
             msg_disable ();
-            match = data_in (ss_buffer (value, width), LEGACY_NATIVE,
-                             FMT_F, 0, 0, 0, trns->dst_dict,  &uv, 0);
+            match = data_in (ss_buffer (CHAR_CAST_BUG (char *, value), width),
+                             LEGACY_NATIVE, FMT_F, 0, 0, 0, trns->dst_dict,
+                             &uv, 0);
             msg_enable ();
             out->value.f = uv.f;
             break;
index 1e33857c1e3afa0a879512378df55694ca3900bc..5c64fac864a8e1eb78588dcc7558177d759ce0e1 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2009 Free Software Foundation, Inc.
+   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -18,6 +18,7 @@
 #define LIBPSPP_CAST_H 1
 
 #include <stddef.h>
+#include "gl/verify.h"
 
 /* Expands to a void expression that checks that POINTER is an
    expression whose type is a qualified or unqualified version of
         (CHECK_POINTER_HAS_TYPE (POINTER, TYPE),        \
          (TYPE) (POINTER))
 
+/* Casts POINTER to TYPE.  Yields a compiler diagnostic if either TYPE or
+   POINTER is not a pointer to character type.
+
+   PSPP uses "unsigned char" (actually uint8_t) in "union value" and "char"
+   elsewhere to emphasize that data in union value usually requires reencoding
+   when transferred to and from other string types.  These macros suppress the
+   warning when implicitly converting between pointers to different character
+   types, so their use normally marks a bug that should eventually be fixed.
+   However, until these bugs are fixed, suppressing the warnings is much less
+   annoying.
+
+   Use CHAR_CAST_BUG if you think there is a bug to be fixed, or if you have
+   not yet carefully examined the situation, or if you are not sure.
+   Use CHAR_CAST if you are convinced that this is actually a correct cast. */
+#define CHAR_CAST(TYPE, POINTER)                                \
+        ((void) verify_true (sizeof (*(POINTER)) == 1),         \
+         (void) (sizeof (*(POINTER) + 1)),                      \
+         (void) verify_true (sizeof (*(TYPE) NULL) == 1),       \
+         (void) (sizeof (*(TYPE) NULL + 1)),                    \
+         (TYPE) (POINTER))
+#define CHAR_CAST_BUG(TYPE, POINTER) CHAR_CAST(TYPE, POINTER)
+
 /* Given POINTER, a pointer to the given MEMBER within structure
    STRUCT, returns the address of the STRUCT. */
 #define UP_CAST(POINTER, STRUCT, MEMBER)                                \
index 22e717ac965903acdb5a8b12f95e5e3dd6492832..229e478161299794664b7048eb464fb69b7bfb81 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2008 Free Software Foundation, Inc.
+   Copyright (C) 2008, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 #include <ctype.h>
 #include <mbchar.h>
 
-#include <data/data-in.h>
-#include <data/data-out.h>
-#include <data/format.h>
-#include <data/value.h>
-#include <libpspp/assertion.h>
-#include <libpspp/message.h>
-#include <libpspp/str.h>
+#include "data/data-in.h"
+#include "data/data-out.h"
+#include "data/format.h"
+#include "data/value.h"
+#include "libpspp/assertion.h"
+#include "libpspp/cast.h"
+#include "libpspp/message.h"
+#include "libpspp/str.h"
 
 /* Appends to OUTPUT a pair of hex digits for each byte in IN. */
 static void
@@ -197,7 +198,10 @@ syntax_gen_value (struct string *output, const union value *value, int width,
   if (width == 0)
     syntax_gen_number (output, value->f, format);
   else
-    syntax_gen_string (output, ss_buffer (value_str (value, width), width));
+    {
+      char *s = CHAR_CAST_BUG (char *, value_str (value, width));
+      syntax_gen_string (output, ss_buffer (s, width));
+    }
 }
 
 /* Appends <low> THRU <high> to OUTPUT.  If LOW is LOWEST, then