X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=inline;f=src%2Flanguage%2Fcontrol%2Frepeat.c;h=118e8d3ccd4fd8c56c075c9512d735945f4e6cd9;hb=a5f6c8f299c416a9cd0ad778b3988435b66fae33;hp=e76c4903dea02e6b07c653201a9ff38dfef4f2ce;hpb=4881184f738deb7a4c5b843a361d4225f4e3d6c0;p=pspp diff --git a/src/language/control/repeat.c b/src/language/control/repeat.c index e76c4903de..118e8d3ccd 100644 --- a/src/language/control/repeat.c +++ b/src/language/control/repeat.c @@ -30,6 +30,7 @@ #include "libpspp/cast.h" #include "libpspp/hash-functions.h" #include "libpspp/hmap.h" +#include "libpspp/i18n.h" #include "libpspp/message.h" #include "libpspp/str.h" #include "libpspp/misc.h" @@ -37,6 +38,7 @@ #include "gl/ftoastr.h" #include "gl/minmax.h" #include "gl/xalloc.h" +#include "gl/xmemdup0.h" #include "gettext.h" #define _(msgid) gettext (msgid) @@ -45,6 +47,7 @@ struct dummy_var { struct hmap_node hmap_node; char *name; + size_t name_len; char **values; size_t n_values; }; @@ -78,7 +81,7 @@ cmd_do_repeat (struct lexer *lexer, struct dataset *ds) static unsigned int hash_dummy (const char *name, size_t name_len) { - return hash_case_bytes (name, name_len, 0); + return utf8_hash_case_bytes (name, name_len, 0); } static const struct dummy_var * @@ -88,7 +91,7 @@ find_dummy_var (struct hmap *hmap, const char *name, size_t name_len) HMAP_FOR_EACH_WITH_HASH (dv, struct dummy_var, hmap_node, hash_dummy (name, name_len), hmap) - if (strcasecmp (dv->name, name)) + if (!utf8_strncasecmp (dv->name, dv->name_len, name, name_len)) return dv; return NULL; @@ -116,7 +119,9 @@ parse_specification (struct lexer *lexer, struct dictionary *dict, if (dict_lookup_var (dict, name)) msg (SW, _("Dummy variable name `%s' hides dictionary variable `%s'."), name, name); - if (find_dummy_var (dummies, name, strlen (name))) + + size_t name_len = strlen (name); + if (find_dummy_var (dummies, name, name_len)) { msg (SE, _("Dummy variable name `%s' is given twice."), name); goto error; @@ -124,7 +129,8 @@ parse_specification (struct lexer *lexer, struct dictionary *dict, /* Make a new macro. */ dv = xmalloc (sizeof *dv); - dv->name = xstrdup (name); + dv->name = xmemdup0 (name, name_len); + dv->name_len = name_len; dv->values = NULL; dv->n_values = 0; hmap_insert (dummies, &dv->hmap_node, hash_dummy (name, strlen (name))); @@ -204,7 +210,7 @@ do_parse_commands (struct substring s, enum segmenter_mode mode, enum segment_type type; int n; - n = segmenter_push (&segmenter, s.string, s.length, &type); + n = segmenter_push (&segmenter, s.string, s.length, true, &type); assert (n >= 0); if (type == SEG_DO_REPEAT_COMMAND) @@ -214,7 +220,7 @@ do_parse_commands (struct substring s, enum segmenter_mode mode, int k; k = segmenter_push (&segmenter, s.string + n, s.length - n, - &type); + true, &type); if (type != SEG_NEWLINE && type != SEG_DO_REPEAT_COMMAND) break; @@ -246,8 +252,6 @@ do_parse_commands (struct substring s, enum segmenter_mode mode, static bool parse_commands (struct lexer *lexer, struct hmap *dummies) { - enum lex_syntax_mode syntax_mode; - enum segmenter_mode mode; struct string *outputs; struct string input; size_t n_values; @@ -269,25 +273,14 @@ parse_commands (struct lexer *lexer, struct hmap *dummies) ds_put_byte (&input, '\n'); lex_get (lexer); } - if (ds_is_empty (&input)) - ds_put_byte (&input, '\n'); - ds_put_byte (&input, '\0'); n_values = count_values (dummies); outputs = xmalloc (n_values * sizeof *outputs); for (i = 0; i < n_values; i++) ds_init_empty (&outputs[i]); - syntax_mode = lex_get_syntax_mode (lexer); - if (syntax_mode == LEX_SYNTAX_AUTO) - mode = SEG_MODE_AUTO; - else if (syntax_mode == LEX_SYNTAX_INTERACTIVE) - mode = SEG_MODE_INTERACTIVE; - else if (syntax_mode == LEX_SYNTAX_BATCH) - mode = SEG_MODE_BATCH; - else - NOT_REACHED (); - do_parse_commands (ds_ss (&input), mode, dummies, outputs, n_values); + do_parse_commands (ds_ss (&input), lex_get_syntax_mode (lexer), + dummies, outputs, n_values); ds_destroy (&input); @@ -304,9 +297,8 @@ parse_commands (struct lexer *lexer, struct hmap *dummies) for (i = 0; i < n_values; i++) { struct string *output = &outputs[n_values - i - 1]; - struct lex_reader *reader; - - reader = lex_reader_for_substring_nocopy (ds_ss (output)); + const char *encoding = lex_get_encoding (lexer); + struct lex_reader *reader = lex_reader_for_substring_nocopy (ds_ss (output), encoding); lex_reader_set_file_name (reader, file_name); reader->line_number = line_number; lex_include (lexer, reader); @@ -369,23 +361,20 @@ parse_numbers (struct lexer *lexer, struct dummy_var *dv) if (lex_next_token (lexer, 1) == T_TO) { - long int a, b; - long int i; - if (!lex_is_integer (lexer)) { msg (SE, _("Ranges may only have integer bounds.")); return false; } - a = lex_integer (lexer); + long a = lex_integer (lexer); lex_get (lexer); lex_get (lexer); - if (!lex_force_int (lexer)) + if (!lex_force_int_range (lexer, NULL, a, LONG_MAX)) return false; - b = lex_integer (lexer); + long b = lex_integer (lexer); if (b < a) { msg (SE, _("%ld TO %ld is an invalid range."), a, b); @@ -393,7 +382,7 @@ parse_numbers (struct lexer *lexer, struct dummy_var *dv) } lex_get (lexer); - for (i = a; i <= b; i++) + for (long i = a; i <= b; i++) add_replacement (dv, xasprintf ("%ld", i), &allocated); } else @@ -438,6 +427,6 @@ parse_strings (struct lexer *lexer, struct dummy_var *dv) int cmd_end_repeat (struct lexer *lexer UNUSED, struct dataset *ds UNUSED) { - msg (SE, _("No matching DO REPEAT.")); + msg (SE, _("No matching %s."), "DO REPEAT"); return CMD_CASCADING_FAILURE; }