| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
|
|
| #include <config.h> |
|
|
| |
| #include "test-u32-normalize-big.h" |
|
|
| #if GNULIB_TEST_UNINORM_U32_NORMALIZE |
|
|
| #include <stdio.h> |
| #include <stdlib.h> |
|
|
| #include "xalloc.h" |
| #include "unistr.h" |
| #define NO_MAIN_HERE |
| #include "macros.h" |
|
|
| #define ASSERT_WITH_LINE(expr, file, line) \ |
| do \ |
| { \ |
| if (!(expr)) \ |
| { \ |
| fprintf (stderr, "%s:%d: assertion failed for %s:%u\n", \ |
| __FILE__, __LINE__, file, line); \ |
| fflush (stderr); \ |
| abort (); \ |
| } \ |
| } \ |
| while (0) |
|
|
| static int |
| cmp_ucs4_t (const void *a, const void *b) |
| { |
| ucs4_t a_value = *(const ucs4_t *)a; |
| ucs4_t b_value = *(const ucs4_t *)b; |
| return (a_value < b_value ? -1 : a_value > b_value ? 1 : 0); |
| } |
|
|
| void |
| read_normalization_test_file (const char *filename, |
| struct normalization_test_file *file) |
| { |
| FILE *stream; |
| unsigned int lineno; |
| int part_index; |
| struct normalization_test_line *lines; |
| size_t lines_length; |
| size_t lines_allocated; |
|
|
| stream = fopen (filename, "r"); |
| if (stream == NULL) |
| { |
| fprintf (stderr, "error during fopen of '%s'\n", filename); |
| exit (1); |
| } |
|
|
| for (part_index = 0; part_index < 6; part_index++) |
| { |
| file->parts[part_index].lines = NULL; |
| file->parts[part_index].lines_length = 0; |
| } |
|
|
| lineno = 0; |
|
|
| part_index = -1; |
| lines = NULL; |
| lines_length = 0; |
| lines_allocated = 0; |
|
|
| for (;;) |
| { |
| char buf[1000+1]; |
| char *ptr; |
| int c; |
| struct normalization_test_line line; |
| size_t sequence_index; |
|
|
| lineno++; |
|
|
| |
| ptr = buf; |
| do |
| { |
| c = getc (stream); |
| if (c == EOF || c == '\n') |
| break; |
| *ptr++ = c; |
| } |
| while (ptr < buf + 1000); |
| *ptr = '\0'; |
| if (c == EOF) |
| break; |
|
|
| |
| if (buf[0] == '\0' || buf[0] == '#') |
| continue; |
|
|
| |
| if (buf[0] == '@') |
| { |
| |
| if (part_index >= 0) |
| { |
| lines = |
| (struct normalization_test_line *) |
| xreallocarray (lines, lines_length, sizeof *lines); |
| file->parts[part_index].lines = lines; |
| file->parts[part_index].lines_length = lines_length; |
| } |
| part_index++; |
| lines = NULL; |
| lines_length = 0; |
| lines_allocated = 0; |
| continue; |
| } |
|
|
| |
| |
| if (!(part_index >= 0 && part_index < 6)) |
| { |
| fprintf (stderr, "unexpected structure of '%s'\n", filename); |
| exit (1); |
| } |
| ptr = buf; |
| line.lineno = lineno; |
| for (sequence_index = 0; sequence_index < 5; sequence_index++) |
| line.sequences[sequence_index] = NULL; |
| for (sequence_index = 0; sequence_index < 5; sequence_index++) |
| { |
| uint32_t *sequence = XNMALLOC (1, uint32_t); |
| size_t sequence_length = 0; |
|
|
| for (;;) |
| { |
| char *endptr; |
| unsigned int uc; |
|
|
| uc = strtoul (ptr, &endptr, 16); |
| if (endptr == ptr) |
| break; |
| ptr = endptr; |
|
|
| |
| sequence = |
| (uint32_t *) |
| xreallocarray (sequence, sequence_length + 2, sizeof *sequence); |
| sequence[sequence_length] = uc; |
| sequence_length++; |
|
|
| if (*ptr == ' ') |
| ptr++; |
| } |
| if (sequence_length == 0) |
| { |
| fprintf (stderr, "empty character sequence in '%s'\n", filename); |
| exit (1); |
| } |
| sequence[sequence_length] = 0; |
|
|
| line.sequences[sequence_index] = sequence; |
|
|
| if (*ptr != ';') |
| { |
| fprintf (stderr, "error parsing '%s'\n", filename); |
| exit (1); |
| } |
| ptr++; |
| } |
|
|
| |
| if (lines_length == lines_allocated) |
| { |
| lines_allocated = 2 * lines_allocated; |
| if (lines_allocated < 7) |
| lines_allocated = 7; |
| lines = |
| (struct normalization_test_line *) |
| xreallocarray (lines, lines_allocated, sizeof *lines); |
| } |
| lines[lines_length] = line; |
| lines_length++; |
| } |
|
|
| if (part_index >= 0) |
| { |
| lines = |
| (struct normalization_test_line *) |
| xreallocarray (lines, lines_length, sizeof *lines); |
| file->parts[part_index].lines = lines; |
| file->parts[part_index].lines_length = lines_length; |
| } |
|
|
| { |
| |
| const struct normalization_test_part *p = &file->parts[1]; |
| ucs4_t *c1_array = XNMALLOC (p->lines_length + 1, ucs4_t); |
| size_t line_index; |
|
|
| for (line_index = 0; line_index < p->lines_length; line_index++) |
| { |
| const uint32_t *sequence = p->lines[line_index].sequences[0]; |
| |
| if (!(sequence[0] != 0 && sequence[1] == 0)) |
| abort (); |
| c1_array[line_index] = sequence[0]; |
| } |
|
|
| |
| qsort (c1_array, p->lines_length, sizeof (ucs4_t), cmp_ucs4_t); |
|
|
| |
| c1_array[p->lines_length] = 0x110000; |
|
|
| file->part1_c1_sorted = c1_array; |
| } |
|
|
| file->filename = xstrdup (filename); |
|
|
| if (ferror (stream) || fclose (stream)) |
| { |
| fprintf (stderr, "error reading from '%s'\n", filename); |
| exit (1); |
| } |
| } |
|
|
| void |
| test_specific (const struct normalization_test_file *file, |
| int (*check) (const uint32_t *c1, size_t c1_length, |
| const uint32_t *c2, size_t c2_length, |
| const uint32_t *c3, size_t c3_length, |
| const uint32_t *c4, size_t c4_length, |
| const uint32_t *c5, size_t c5_length)) |
| { |
| size_t part_index; |
|
|
| for (part_index = 0; part_index < 6; part_index++) |
| { |
| const struct normalization_test_part *p = &file->parts[part_index]; |
| size_t line_index; |
|
|
| for (line_index = 0; line_index < p->lines_length; line_index++) |
| { |
| const struct normalization_test_line *l = &p->lines[line_index]; |
|
|
| ASSERT_WITH_LINE (check (l->sequences[0], u32_strlen (l->sequences[0]), |
| l->sequences[1], u32_strlen (l->sequences[1]), |
| l->sequences[2], u32_strlen (l->sequences[2]), |
| l->sequences[3], u32_strlen (l->sequences[3]), |
| l->sequences[4], u32_strlen (l->sequences[4])) |
| == 0, |
| file->filename, l->lineno); |
| } |
| } |
| } |
|
|
| void |
| test_other (const struct normalization_test_file *file, uninorm_t nf) |
| { |
| |
| |
| |
| const ucs4_t *p = file->part1_c1_sorted; |
| ucs4_t uc; |
|
|
| for (uc = 0; uc < 0x110000; uc++) |
| { |
| if (uc >= 0xD800 && uc < 0xE000) |
| { |
| |
| } |
| else if (uc == *p) |
| { |
| |
| p++; |
| } |
| else |
| { |
| uint32_t input[1]; |
| size_t length; |
| uint32_t *result; |
|
|
| input[0] = uc; |
| result = u32_normalize (nf, input, 1, NULL, &length); |
| ASSERT (result != NULL && length == 1 && result[0] == uc); |
|
|
| free (result); |
| } |
| } |
| } |
|
|
| void |
| free_normalization_test_file (struct normalization_test_file *file) |
| { |
| size_t part_index; |
|
|
| for (part_index = 0; part_index < 6; part_index++) |
| { |
| const struct normalization_test_part *p = &file->parts[part_index]; |
| size_t line_index; |
|
|
| for (line_index = 0; line_index < p->lines_length; line_index++) |
| { |
| const struct normalization_test_line *l = &p->lines[line_index]; |
| size_t sequence_index; |
|
|
| for (sequence_index = 0; sequence_index < 5; sequence_index++) |
| free (l->sequences[sequence_index]); |
| } |
| free (p->lines); |
| } |
| free (file->part1_c1_sorted); |
| free (file->filename); |
| } |
|
|
| #endif |
|
|