From d775f576e4ffc0973c5f183b57b2baa089f555dc Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 17 Sep 2010 21:03:57 -0700 Subject: [PATCH] Suppress warnings about conversions between char * and unsigned char *. 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 | 9 ++++++--- src/language/lexer/value-parser.c | 27 +++++++++++++++---------- src/language/xforms/compute.c | 12 ++++++----- src/language/xforms/recode.c | 10 +++++---- src/libpspp/cast.h | 25 ++++++++++++++++++++++- src/ui/syntax-gen.c | 22 +++++++++++--------- 6 files changed, 72 insertions(+), 33 deletions(-) diff --git a/src/language/expressions/operations.def b/src/language/expressions/operations.def index 844cab7e17..c25f113c31 100644 --- a/src/language/expressions/operations.def +++ b/src/language/expressions/operations.def @@ -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; } diff --git a/src/language/lexer/value-parser.c b/src/language/lexer/value-parser.c index c780d86f04..c492658e28 100644 --- a/src/language/lexer/value-parser.c +++ b/src/language/lexer/value-parser.c @@ -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 @@ -15,14 +15,18 @@ along with this program. If not, see . */ #include + #include "value-parser.h" + #include -#include -#include -#include "lexer.h" -#include -#include -#include + +#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); diff --git a/src/language/xforms/compute.c b/src/language/xforms/compute.c index 09fc2155ab..a508933c68 100644 --- a/src/language/xforms/compute.c +++ b/src/language/xforms/compute.c @@ -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; diff --git a/src/language/xforms/recode.c b/src/language/xforms/recode.c index 62b03ba073..f4a19a9c9e 100644 --- a/src/language/xforms/recode.c +++ b/src/language/xforms/recode.c @@ -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; diff --git a/src/libpspp/cast.h b/src/libpspp/cast.h index 1e33857c1e..5c64fac864 100644 --- a/src/libpspp/cast.h +++ b/src/libpspp/cast.h @@ -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 +#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 @@ -83,6 +84,28 @@ (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) \ diff --git a/src/ui/syntax-gen.c b/src/ui/syntax-gen.c index 22e717ac96..229e478161 100644 --- a/src/ui/syntax-gen.c +++ b/src/ui/syntax-gen.c @@ -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 @@ -21,13 +21,14 @@ #include #include -#include -#include -#include -#include -#include -#include -#include +#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 THRU to OUTPUT. If LOW is LOWEST, then -- 2.30.2