+/** @brief Run breaking tests for utf32_is_gcb() etc */
+static void breaktest(const char *path,
+ int (*breakfn)(const uint32_t *, size_t, size_t)) {
+ FILE *fp = open_unicode_test(path);
+ int lineno = 0;
+ char *l, *lp;
+ size_t bn, n;
+ char break_allowed[1024];
+ uint32_t buffer[1024];
+
+ while(!inputline(path, fp, &l, '\n')) {
+ ++lineno;
+ if(l[0] == '#') continue;
+ bn = 0;
+ lp = l;
+ while(*lp) {
+ if(*lp == ' ' || *lp == '\t') {
+ ++lp;
+ continue;
+ }
+ if(*lp == '#')
+ break;
+ if((unsigned char)*lp == 0xC3 && (unsigned char)lp[1] == 0xB7) {
+ /* 00F7 DIVISION SIGN */
+ break_allowed[bn] = 1;
+ lp += 2;
+ continue;
+ }
+ if((unsigned char)*lp == 0xC3 && (unsigned char)lp[1] == 0x97) {
+ /* 00D7 MULTIPLICATION SIGN */
+ break_allowed[bn] = 0;
+ lp += 2;
+ continue;
+ }
+ if(isxdigit((unsigned char)*lp)) {
+ buffer[bn++] = strtoul(lp, &lp, 16);
+ continue;
+ }
+ fatal(0, "%s:%d: evil line: %s", path, lineno, l);
+ }
+ for(n = 0; n <= bn; ++n) {
+ if(breakfn(buffer, bn, n) != break_allowed[n]) {
+ fprintf(stderr,
+ "%s:%d: offset %zu: mismatch\n",
+ path, lineno, n);
+ count_error();
+ }
+ ++tests;
+ }
+ xfree(l);
+ }
+ fclose(fp);
+}
+