X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fshort-names.c;h=ff6b4ff7739d0793a6f2b4c8bbb314b21281a7d7;hb=refs%2Fheads%2Fctables7;hp=08bf7587876b4ac56d2b54bd8cc801c00bdd04f2;hpb=c725a4f64718ef1ee4139c27c94b2eb6447b51b4;p=pspp diff --git a/src/data/short-names.c b/src/data/short-names.c index 08bf758787..ff6b4ff773 100644 --- a/src/data/short-names.c +++ b/src/data/short-names.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007, 2009, 2010, 2011, 2014 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 @@ -16,81 +16,35 @@ #include -#include +#include "data/short-names.h" -#include -#include -#include -#include -#include -#include -#include -#include +#include "data/dictionary.h" +#include "data/sys-file-private.h" +#include "data/variable.h" +#include "libpspp/assertion.h" +#include "libpspp/compiler.h" +#include "libpspp/i18n.h" +#include "libpspp/message.h" +#include "libpspp/str.h" +#include "libpspp/stringi-set.h" #include "gettext.h" #define _(msgid) gettext (msgid) -/* Compares two strings. */ -static int -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, const void *aux UNUSED) -{ - return hsh_hash_string (s); -} - -/* Sets V's short name to BASE, followed by a suffix of the form - _A, _B, _C, ..., _AA, _AB, etc. according to the value of - SUFFIX_NUMBER. Truncates BASE as necessary to fit. */ static void -set_var_short_name_suffix (struct variable *v, size_t i, - const char *base, int suffix_number) -{ - char suffix[SHORT_NAME_LEN + 1]; - char short_name[SHORT_NAME_LEN + 1]; - int len, ofs; - - assert (suffix_number >= 0); - - /* Set base name. */ - var_set_short_name (v, i, base); - - /* Compose suffix. */ - suffix[0] = '_'; - if (!str_format_26adic (suffix_number, &suffix[1], sizeof suffix - 1)) - msg (SE, _("Variable suffix too large.")); - len = strlen (suffix); - - /* Append suffix to V's short name. */ - str_copy_trunc (short_name, sizeof short_name, base); - if (strlen (short_name) + len > SHORT_NAME_LEN) - ofs = SHORT_NAME_LEN - len; - else - ofs = strlen (short_name); - strcpy (short_name + ofs, suffix); - - /* Set name. */ - var_set_short_name (v, i, short_name); -} - -static void -claim_short_name (struct variable *v, size_t i, struct hsh_table *short_names) +claim_short_name (struct variable *v, size_t i, + struct stringi_set *short_names) { const char *short_name = var_get_short_name (v, i); - if (short_name != NULL - && hsh_insert (short_names, (char *) short_name) != NULL) + if (short_name != NULL && !stringi_set_insert (short_names, short_name)) var_set_short_name (v, i, NULL); } /* Form initial short_name from the variable name, then try _A, _B, ... _AA, _AB, etc., if needed. */ static void -assign_short_name (struct variable *v, size_t i, struct hsh_table *short_names) +assign_short_name (struct variable *v, size_t i, + struct stringi_set *short_names) { int trial; @@ -99,13 +53,28 @@ assign_short_name (struct variable *v, size_t i, struct hsh_table *short_names) for (trial = 0; ; trial++) { + char suffix[SHORT_NAME_LEN + 1]; + char *short_name; + + /* Compose suffix. */ if (trial == 0) - var_set_short_name (v, i, var_get_name (v)); + suffix[0] = '\0'; else - set_var_short_name_suffix (v, i, var_get_name (v), trial); + { + suffix[0] = '_'; + str_format_26adic (trial, true, &suffix[1], sizeof suffix - 1); + } - if (hsh_insert (short_names, (char *) var_get_short_name (v, i)) == NULL) - break; + /* Set name. */ + short_name = utf8_encoding_concat (var_get_name (v), suffix, + var_get_encoding (v), SHORT_NAME_LEN); + if (stringi_set_insert (short_names, short_name)) + { + var_set_short_name (v, i, short_name); + free (short_name); + return; + } + free (short_name); } } @@ -120,23 +89,17 @@ assign_short_name (struct variable *v, size_t i, struct hsh_table *short_names) void short_names_assign (struct dictionary *d) { - size_t var_cnt = dict_get_var_cnt (d); - struct hsh_table *short_names; - size_t i, j; + size_t n_vars = dict_get_n_vars (d); + struct stringi_set short_names; - /* Create hash used for detecting conflicts. The entries in - the hash table point to strings owned by dictionary - variables, not by us, so we don't need to provide a free - function. */ - short_names = hsh_create (var_cnt, compare_strings, hash_string, - NULL, NULL); + stringi_set_init (&short_names); /* Clear short names that conflict with a variable name. */ - for (i = 0; i < var_cnt; i++) + for (size_t i = 0; i < n_vars; i++) { struct variable *v = dict_get_var (d, i); - int segment_cnt = sfm_width_to_segments (var_get_width (v)); - for (j = 0; j < segment_cnt; j++) + int n_segments = sfm_width_to_segments (var_get_width (v)); + for (size_t j = 0; j < n_segments; j++) { const char *name = var_get_short_name (v, j); if (name != NULL) @@ -150,11 +113,13 @@ short_names_assign (struct dictionary *d) /* Give variables whose names are short the corresponding short name. */ - for (i = 0; i < var_cnt; i++) + for (size_t i = 0; i < n_vars; i++) { struct variable *v = dict_get_var (d, i); - if (strlen (var_get_name (v)) <= SHORT_NAME_LEN) - var_set_short_name (v, 0, var_get_name (v)); + const char *name = var_get_name (v); + int len = recode_string_len (var_get_encoding (v), "UTF-8", name, -1); + if (len <= SHORT_NAME_LEN) + var_set_short_name (v, 0, name); } /* Each variable with an assigned short name for its first @@ -162,34 +127,33 @@ short_names_assign (struct dictionary *d) conflict, the claimant earlier in dictionary order wins. Then similarly for additional segments of very long strings. */ - for (i = 0; i < var_cnt; i++) + for (size_t i = 0; i < n_vars; i++) { struct variable *v = dict_get_var (d, i); - claim_short_name (v, 0, short_names); + claim_short_name (v, 0, &short_names); } - for (i = 0; i < var_cnt; i++) + for (size_t i = 0; i < n_vars; i++) { struct variable *v = dict_get_var (d, i); - int segment_cnt = sfm_width_to_segments (var_get_width (v)); - for (j = 1; j < segment_cnt; j++) - claim_short_name (v, j, short_names); + int n_segments = sfm_width_to_segments (var_get_width (v)); + for (size_t j = 1; j < n_segments; j++) + claim_short_name (v, j, &short_names); } /* Assign short names to first segment of remaining variables, then similarly for additional segments. */ - for (i = 0; i < var_cnt; i++) + for (size_t i = 0; i < n_vars; i++) { struct variable *v = dict_get_var (d, i); - assign_short_name (v, 0, short_names); + assign_short_name (v, 0, &short_names); } - for (i = 0; i < var_cnt; i++) + for (size_t i = 0; i < n_vars; i++) { struct variable *v = dict_get_var (d, i); - int segment_cnt = sfm_width_to_segments (var_get_width (v)); - for (j = 1; j < segment_cnt; j++) - assign_short_name (v, j, short_names); + int n_segments = sfm_width_to_segments (var_get_width (v)); + for (size_t j = 1; j < n_segments; j++) + assign_short_name (v, j, &short_names); } - /* Get rid of hash table. */ - hsh_destroy (short_names); + stringi_set_destroy (&short_names); }