X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=tests%2Flanguage%2Flexer%2Fsegment-test.c;h=2cd141cfe01598972fc83f97a26cf871d4912088;hb=25bc101890a62f780da3a7c6af71ecc3ce09fdb1;hp=64243c8a7163a1778e0a8399a8435bc8ac1b5760;hpb=fe8dc2171009e90d2335f159d05f7e6660e24780;p=pspp diff --git a/tests/language/lexer/segment-test.c b/tests/language/lexer/segment-test.c index 64243c8a71..2cd141cfe0 100644 --- a/tests/language/lexer/segment-test.c +++ b/tests/language/lexer/segment-test.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 2010, 2011, 2013 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 @@ -36,6 +36,7 @@ #include "gl/progname.h" #include "gl/read-file.h" #include "gl/xalloc.h" +#include "gl/xmemdup0.h" /* -a/--auto, -b/--batch, -i/--interactive: syntax mode. */ static enum segmenter_mode mode = SEG_MODE_AUTO; @@ -46,18 +47,25 @@ static bool verbose; /* -1, --one-byte: Feed in one byte at a time? */ static bool one_byte; +/* -0, --truncations: Check that every truncation of input yields a result. */ +static bool check_truncations; + +/* -s, --strip-trailing-newline: Strip trailing newline from last line of + input. */ +static bool strip_trailing_newline; + static const char *parse_options (int argc, char **argv); static void usage (void) NO_RETURN; +static void check_segmentation (const char *input, size_t length, + bool print_segments); + int main (int argc, char *argv[]) { - size_t offset, line_number, line_offset; const char *file_name; - char *input; - struct segmenter s; size_t length; - int prev_type; + char *input; set_program_name (argv[0]); file_name = parse_options (argc, argv); @@ -69,19 +77,45 @@ main (int argc, char *argv[]) : read_file (file_name, &length)); if (input == NULL) error (EXIT_FAILURE, errno, "reading %s failed", file_name); - input = xrealloc (input, length + 3); - if (length == 0 || input[length - 1] != '\n') - input[length++] = '\n'; - input[length++] = '\0'; + if (strip_trailing_newline && length && input[length - 1] == '\n') + { + length--; + if (length && input[length - 1] == '\r') + length--; + } + + if (!check_truncations) + check_segmentation (input, length, true); + else + { + size_t test_len; + + for (test_len = 0; test_len <= length; test_len++) + { + char *copy = xmemdup (input, test_len); + check_segmentation (copy, test_len, false); + free (copy); + } + } + free (input); + + return 0; +} + +static void +check_segmentation (const char *input, size_t length, bool print_segments) +{ + struct segmenter s; segmenter_init (&s, mode); - line_number = 1; - line_offset = 0; - prev_type = -1; - for (offset = 0; offset < length; ) + size_t line_number = 1; + size_t line_offset = 0; + int prev_type = -1; + size_t offset = 0; + enum segment_type type; + do { - enum segment_type type; const char *type_name, *p; int n; @@ -100,7 +134,7 @@ main (int argc, char *argv[]) n_newlines++; copy = xmemdup (input + offset, i); - n = segmenter_push (&s, copy, i, &type); + n = segmenter_push (&s, copy, i, i + offset >= length, &type); free (copy); if (n >= 0) @@ -109,20 +143,33 @@ main (int argc, char *argv[]) assert (n_newlines <= 2); } else - n = segmenter_push (&s, input + offset, length - offset, &type); + n = segmenter_push (&s, input + offset, length - offset, true, &type); if (n < 0) - error (EXIT_FAILURE, 0, "segmenter_push returned -1 at offset %zu", - offset); + { + if (!print_segments) + check_segmentation (input, length, true); + else + error (EXIT_FAILURE, 0, "segmenter_push returned -1 at offset %zu", + offset); + } assert (offset + n <= length); if (type == SEG_NEWLINE) - assert ((n == 1 && input[offset] == '\n') - || (n == 2 - && input[offset] == '\r' && input[offset + 1] == '\n')); + { + assert ((n == 1 && input[offset] == '\n') + || (n == 2 + && input[offset] == '\r' && input[offset + 1] == '\n')); + } else assert (memchr (&input[offset], '\n', n) == NULL); + if (!print_segments) + { + offset += n; + continue; + } + if (!verbose) { if (prev_type != SEG_SPACES && prev_type != -1 @@ -228,11 +275,10 @@ main (int argc, char *argv[]) printf (" (%s)\n", prompt_style_to_string (prompt)); } } - putchar ('\n'); + while (type != SEG_END); - free (input); - - return 0; + if (print_segments) + putchar ('\n'); } static const char * @@ -243,6 +289,8 @@ parse_options (int argc, char **argv) static const struct option options[] = { {"one-byte", no_argument, NULL, '1'}, + {"truncations", no_argument, NULL, '0'}, + {"strip-trailing-newline", no_argument, NULL, 's'}, {"auto", no_argument, NULL, 'a'}, {"batch", no_argument, NULL, 'b'}, {"interactive", no_argument, NULL, 'i'}, @@ -251,7 +299,7 @@ parse_options (int argc, char **argv) {NULL, 0, NULL, 0}, }; - int c = getopt_long (argc, argv, "1abivh", options, NULL); + int c = getopt_long (argc, argv, "01abivhs", options, NULL); if (c == -1) break; @@ -261,6 +309,14 @@ parse_options (int argc, char **argv) one_byte = true; break; + case '0': + check_truncations = true; + break; + + case 's': + strip_trailing_newline = true; + break; + case 'a': mode = SEG_MODE_AUTO; break; @@ -308,6 +364,8 @@ usage: %s [OPTIONS] INPUT\n\ \n\ Options:\n\ -1, --one-byte feed one byte at a time\n\ + -0, --truncations check null truncation of each prefix of input\n\ + -s, --strip-trailing-newline remove newline from end of input\n\ -a, --auto use \"auto\" syntax mode\n\ -b, --batch use \"batch\" syntax mode\n\ -i, --interactive use \"interactive\" syntax mode (default)\n\