X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fvariable.c;h=ca302415d22799c4a8547dd398ad601802b3fea3;hb=2997cc6481d0744e910eccb6f23d56efe93d32d3;hp=24363996dd2695120841454c61cb51119d1b0289;hpb=dcf9b154cbcaa35c3d8459a201b77eec8bcb30bd;p=pspp diff --git a/src/data/variable.c b/src/data/variable.c index 24363996dd..ca302415d2 100644 --- a/src/data/variable.c +++ b/src/data/variable.c @@ -19,16 +19,20 @@ #include #include "variable.h" -#include "message.h" +#include +#include #include -#include "alloc.h" +#include +#include #include "dictionary.h" -#include "hash.h" +#include #include "identifier.h" -#include "misc.h" -#include "str.h" +#include +#include #include "value-labels.h" +#include "minmax.h" + #include "gettext.h" #define _(msgid) gettext (msgid) @@ -104,7 +108,7 @@ compare_values (const union value *a, const union value *b, int width) if (width == 0) return a->f < b->f ? -1 : a->f > b->f; else - return memcmp (a->s, b->s, min(MAX_SHORT_STRING, width)); + return memcmp (a->s, b->s, MIN(MAX_SHORT_STRING, width)); } /* Create a hash of v */ @@ -116,7 +120,7 @@ hash_value(const union value *v, int width) if ( 0 == width ) id_hash = hsh_hash_double (v->f); else - id_hash = hsh_hash_bytes (v->s, min(MAX_SHORT_STRING, width)); + id_hash = hsh_hash_bytes (v->s, MIN(MAX_SHORT_STRING, width)); return id_hash; } @@ -130,26 +134,33 @@ hash_value(const union value *v, int width) bool var_is_valid_name (const char *name, bool issue_error) { + bool plausible; size_t length, i; assert (name != NULL); + /* Note that strlen returns number of BYTES, not the number of + CHARACTERS */ length = strlen (name); - if (length < 1) - { - if (issue_error) - msg (SE, _("Variable name cannot be empty string.")); - return false; - } - else if (length > LONG_NAME_LEN) + + plausible = var_is_plausible_name(name, issue_error); + + if ( ! plausible ) + return false; + + + if (!lex_is_id1 (name[0])) { if (issue_error) - msg (SE, _("Variable name %s exceeds %d-character limit."), - name, (int) LONG_NAME_LEN); + msg (SE, _("Character `%c' (in %s), may not appear " + "as the first character in a variable name."), + name[0], name); return false; } + for (i = 0; i < length; i++) + { if (!lex_is_idn (name[i])) { if (issue_error) @@ -158,13 +169,38 @@ var_is_valid_name (const char *name, bool issue_error) name[i], name); return false; } - - if (!lex_is_id1 (name[0])) + } + + return true; +} + +/* + Returns true if NAME is an plausible name for a variable, + false otherwise. If ISSUE_ERROR is true, issues an + explanatory error message on failure. + This function makes no use of LC_CTYPE. +*/ +bool +var_is_plausible_name (const char *name, bool issue_error) +{ + size_t length; + + assert (name != NULL); + + /* Note that strlen returns number of BYTES, not the number of + CHARACTERS */ + length = strlen (name); + if (length < 1) { if (issue_error) - msg (SE, _("Character `%c' (in %s), may not appear " - "as the first character in a variable name."), - name[0], name); + msg (SE, _("Variable name cannot be empty string.")); + return false; + } + else if (length > LONG_NAME_LEN) + { + if (issue_error) + msg (SE, _("Variable name %s exceeds %d-character limit."), + name, (int) LONG_NAME_LEN); return false; } @@ -182,7 +218,7 @@ var_is_valid_name (const char *name, bool issue_error) /* A hsh_compare_func that orders variables A and B by their names. */ int -compare_var_names (const void *a_, const void *b_, void *foo UNUSED) +compare_var_names (const void *a_, const void *b_, const void *aux UNUSED) { const struct variable *a = a_; const struct variable *b = b_; @@ -192,7 +228,7 @@ compare_var_names (const void *a_, const void *b_, void *foo UNUSED) /* A hsh_hash_func that hashes variable V based on its name. */ unsigned -hash_var_name (const void *v_, void *foo UNUSED) +hash_var_name (const void *v_, const void *aux UNUSED) { const struct variable *v = v_; @@ -202,7 +238,7 @@ hash_var_name (const void *v_, void *foo UNUSED) /* A hsh_compare_func that orders pointers to variables A and B by their names. */ int -compare_var_ptr_names (const void *a_, const void *b_, void *foo UNUSED) +compare_var_ptr_names (const void *a_, const void *b_, const void *aux UNUSED) { struct variable *const *a = a_; struct variable *const *b = b_; @@ -213,7 +249,7 @@ compare_var_ptr_names (const void *a_, const void *b_, void *foo UNUSED) /* A hsh_hash_func that hashes pointer to variable V based on its name. */ unsigned -hash_var_ptr_name (const void *v_, void *foo UNUSED) +hash_var_ptr_name (const void *v_, const void *aux UNUSED) { struct variable *const *v = v_; @@ -227,7 +263,7 @@ void var_set_short_name (struct variable *v, const char *short_name) { assert (v != NULL); - assert (short_name[0] == '\0' || var_is_valid_name (short_name, false)); + assert (short_name[0] == '\0' || var_is_plausible_name (short_name, false)); str_copy_trunc (v->short_name, sizeof v->short_name, short_name); str_uppercase (v->short_name); @@ -313,7 +349,28 @@ dict_class_to_name (enum dict_class dict_class) case DC_SCRATCH: return _("scratch"); default: - assert (0); - abort (); + NOT_REACHED (); } } + +/* Return the number of bytes used when writing case_data for a variable + of WIDTH */ +int +width_to_bytes(int width) +{ + assert (width >= 0); + + if ( width == 0 ) + return MAX_SHORT_STRING ; + else if (width <= MAX_LONG_STRING) + return ROUND_UP (width, MAX_SHORT_STRING); + else + { + int chunks = width / EFFECTIVE_LONG_STRING_LENGTH ; + int remainder = width % EFFECTIVE_LONG_STRING_LENGTH ; + int bytes = remainder + (chunks * (MAX_LONG_STRING + 1) ); + return ROUND_UP (bytes, MAX_SHORT_STRING); + } +} + +