From 0655c32db3a849462fbcebd73d8c659d814e794d Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sat, 1 Jan 2011 10:39:07 -0800 Subject: [PATCH] dict: Make dict_make_unique_var_name() return an allocated string. --- src/data/dictionary.c | 52 ++++++++++++++-------------- src/data/dictionary.h | 7 ++-- src/data/gnumeric-reader.c | 13 +++---- src/data/psql-reader.c | 13 +++---- src/ui/gui/text-data-import-dialog.c | 25 ++++++------- 5 files changed, 51 insertions(+), 59 deletions(-) diff --git a/src/data/dictionary.c b/src/data/dictionary.c index 0ca9f9e4..2ad94ca4 100644 --- a/src/data/dictionary.c +++ b/src/data/dictionary.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010, 2011 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 @@ -842,10 +842,10 @@ var_name_is_insertable (const struct dictionary *dict, const char *name) && lex_id_to_token (ss_cstr (name)) == T_ID); } -static bool -make_hinted_name (const struct dictionary *dict, const char *hint, - char name[VAR_NAME_LEN + 1]) +static char * +make_hinted_name (const struct dictionary *dict, const char *hint) { + char name[VAR_NAME_LEN + 1]; bool dropped = false; char *cp; @@ -874,7 +874,7 @@ make_hinted_name (const struct dictionary *dict, const char *hint, unsigned long int i; if (var_name_is_insertable (dict, name)) - return true; + return xstrdup (name); for (i = 0; i < ULONG_MAX; i++) { @@ -889,16 +889,15 @@ make_hinted_name (const struct dictionary *dict, const char *hint, strcpy (&name[ofs], suffix); if (var_name_is_insertable (dict, name)) - return true; + return xstrdup (name); } } - return false; + return NULL; } -static bool -make_numeric_name (const struct dictionary *dict, unsigned long int *num_start, - char name[VAR_NAME_LEN + 1]) +static char * +make_numeric_name (const struct dictionary *dict, unsigned long int *num_start) { unsigned long int number; @@ -906,27 +905,24 @@ make_numeric_name (const struct dictionary *dict, unsigned long int *num_start, number < ULONG_MAX; number++) { + char name[3 + INT_STRLEN_BOUND (number) + 1]; + sprintf (name, "VAR%03lu", number); if (dict_lookup_var (dict, name) == NULL) { if (num_start != NULL) *num_start = number + 1; - return true; + return xstrdup (name); } } - if (num_start != NULL) - *num_start = ULONG_MAX; - return false; + NOT_REACHED (); } -/* Attempts to devise a variable name unique within DICT. - Returns true if successful, in which case the new variable - name is stored into NAME. Returns false if all names that can - be generated have already been taken. (Returning false is - quite unlikely: at least ULONG_MAX unique names can be - generated.) +/* Devises and returns a variable name unique within DICT. The variable name + is owned by the caller, which must free it with free() when it is no longer + needed. HINT, if it is non-null, is used as a suggestion that will be modified for suitability as a variable name and for @@ -937,14 +933,18 @@ make_numeric_name (const struct dictionary *dict, unsigned long int *num_start, value is used. If NUM_START is non-null, then its value is used as the minimum numeric value to check, and it is updated to the next value to be checked. - */ -bool +*/ +char * dict_make_unique_var_name (const struct dictionary *dict, const char *hint, - unsigned long int *num_start, - char name[VAR_NAME_LEN + 1]) + unsigned long int *num_start) { - return ((hint != NULL && make_hinted_name (dict, hint, name)) - || make_numeric_name (dict, num_start, name)); + if (hint != NULL) + { + char *hinted_name = make_hinted_name (dict, hint); + if (hinted_name != NULL) + return hinted_name; + } + return make_numeric_name (dict, num_start); } /* Returns the weighting variable in dictionary D, or a null diff --git a/src/data/dictionary.h b/src/data/dictionary.h index 96529a1b..3455a74f 100644 --- a/src/data/dictionary.h +++ b/src/data/dictionary.h @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2004, 2007, 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 2004, 2007, 2009, 2010, 2011 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 @@ -84,9 +84,8 @@ void dict_rename_var (struct dictionary *, struct variable *, const char *); bool dict_rename_vars (struct dictionary *, struct variable **, char **new_names, size_t count, char **err_name); -bool dict_make_unique_var_name (const struct dictionary *, const char *hint, - unsigned long int *num_start, - char name[]); +char *dict_make_unique_var_name (const struct dictionary *, const char *hint, + unsigned long int *num_start); /* Weight variable. */ double dict_get_case_weight (const struct dictionary *, diff --git a/src/data/gnumeric-reader.c b/src/data/gnumeric-reader.c index 64b29b76..9772d82a 100644 --- a/src/data/gnumeric-reader.c +++ b/src/data/gnumeric-reader.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 2007, 2009, 2010, 2011 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 @@ -504,21 +504,16 @@ gnumeric_open_reader (struct gnumeric_read_info *gri, struct dictionary **dict) for (i = 0 ; i < n_var_specs ; ++i ) { - char name[VAR_NAME_LEN + 1]; + char *name; /* Probably no data exists for this variable, so allocate a default width */ if ( var_spec[i].width == -1 ) var_spec[i].width = GNUMERIC_DEFAULT_WIDTH; - if ( ! dict_make_unique_var_name (r->dict, var_spec[i].name, - &vstart, name)) - { - msg (ME, _("Cannot create variable name from %s"), var_spec[i].name); - goto error; - } - + name = dict_make_unique_var_name (r->dict, var_spec[i].name, &vstart); dict_create_var (r->dict, name, var_spec[i].width); + free (name); } /* Create the first case, and cache it */ diff --git a/src/data/psql-reader.c b/src/data/psql-reader.c index 76b4674d..378a56af 100644 --- a/src/data/psql-reader.c +++ b/src/data/psql-reader.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 2008, 2009, 2010, 2011 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 @@ -180,15 +180,12 @@ create_var (struct psql_reader *r, const struct fmt_spec *fmt, { unsigned long int vx = 0; struct variable *var; - char name[VAR_NAME_LEN + 1]; - - if ( ! dict_make_unique_var_name (r->dict, suggested_name, &vx, name)) - { - msg (ME, _("Cannot create variable name from %s"), suggested_name); - return NULL; - } + char *name; + name = dict_make_unique_var_name (r->dict, suggested_name, &vx); var = dict_create_var (r->dict, name, width); + free (name); + var_set_both_formats (var, fmt); if ( col != -1) diff --git a/src/ui/gui/text-data-import-dialog.c b/src/ui/gui/text-data-import-dialog.c index 8eb4f3c7..562f4f2a 100644 --- a/src/ui/gui/text-data-import-dialog.c +++ b/src/ui/gui/text-data-import-dialog.c @@ -1,5 +1,5 @@ /* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2008, 2009, 2010 Free Software Foundation + Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation 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 @@ -1255,15 +1255,13 @@ choose_column_names (struct import_assistant *ia) name_row = f->variable_names && f->skip_lines ? f->skip_lines : 0; for (col = s->columns; col < &s->columns[s->column_cnt]; col++) { - char name[VAR_NAME_LEN + 1]; - char *hint; + char *hint, *name; hint = name_row ? ss_xstrdup (col->contents[name_row - 1]) : NULL; - if (!dict_make_unique_var_name (dict, hint, &generated_name_count, name)) - NOT_REACHED (); + name = dict_make_unique_var_name (dict, hint, &generated_name_count); free (hint); - col->name = xstrdup (name); + col->name = name; dict_create_var_assert (dict, name, 0); } dict_destroy (dict); @@ -1601,7 +1599,6 @@ prepare_formats_page (struct import_assistant *ia) for (column_idx = 0; column_idx < s->column_cnt; column_idx++) { struct variable *modified_var; - char name[VAR_NAME_LEN + 1]; modified_var = (column_idx < p->modified_var_cnt ? p->modified_vars[column_idx] : NULL); @@ -1610,11 +1607,11 @@ prepare_formats_page (struct import_assistant *ia) struct column *column = &s->columns[column_idx]; struct variable *var; struct fmt_spec format; + char *name; size_t row; /* Choose variable name. */ - if (!dict_make_unique_var_name (dict, column->name, &number, name)) - NOT_REACHED (); + name = dict_make_unique_var_name (dict, column->name, &number); /* Choose variable format. */ fmt_guesser_clear (fg); @@ -1626,13 +1623,17 @@ prepare_formats_page (struct import_assistant *ia) /* Create variable. */ var = dict_create_var_assert (dict, name, fmt_var_width (&format)); var_set_both_formats (var, &format); + + free (name); } else { - if (!dict_make_unique_var_name (dict, var_get_name (modified_var), - &number, name)) - NOT_REACHED (); + char *name; + + name = dict_make_unique_var_name (dict, var_get_name (modified_var), + &number); dict_clone_var_as_assert (dict, modified_var, name); + free (name); } } fmt_guesser_destroy (fg); -- 2.30.2