- if (!collision)
- break;
-
- /* Try other (mul1, mul2) parameters. */
- mul1++; mul2--;
- if (mul2 == 0)
- {
- /* Increment mul1 + mul2. */
- mul2 = mul1;
- mul1 = 1;
- }
- }
-
- fprintf (stream, "#define MUL1 %u\n", mul1);
- fprintf (stream, "#define MUL2 %u\n", mul2);
-
- /* Because the (code1, code2) -> mul1*code1 + mul2*code2 mapping is not
- injective, we need to store also code1 or code2 in the hash table entry.
- Let's choose code2, randomly. */
-
- t.p = 2;
- t.q = 7;
- composition_table_init (&t);
-
- for (ch = 0; ch < 0x110000; ch++)
- {
- unsigned int length;
- unsigned int decomposed[MAX_DECOMP_LENGTH];
- int type = get_decomposition (ch, &length, decomposed);
-
- if (type == UC_DECOMP_CANONICAL
- /* Consider only binary decompositions.
- Exclude singleton decompositions. */
- && length == 2)
- {
- unsigned int code1 = decomposed[0];
- unsigned int code2 = decomposed[1];
- unsigned int combined = ch;
-
- /* Exclude decompositions where the first part is not a starter,
- i.e. is not of canonical combining class 0. */
- if (strcmp (unicode_attributes[code1].combining, "0") == 0
- /* Exclude characters listed in CompositionExclusions.txt. */
- && !unicode_composition_exclusions[combined])
- {
- /* The combined character must now also be a starter.
- Verify this. */
- if (strcmp (unicode_attributes[combined].combining, "0") != 0)
- abort ();
-
- if (!(code2 < 0x10000))
- abort ();
- if (!(combined < 0x10000))
- abort ();
-
- composition_table_add (&t, mul1 * code1 + mul2 * code2, (code2 << 16) | combined);
- }
- }
- }
-
- composition_table_finalize (&t);
-
- /* Offsets in t.result, in memory of this process. */
- level1_offset =
- 5 * sizeof (uint32_t);
- level2_offset =
- 5 * sizeof (uint32_t)
- + t.level1_size * sizeof (uint32_t);
- level3_offset =
- 5 * sizeof (uint32_t)
- + t.level1_size * sizeof (uint32_t)
- + (t.level2_size << t.q) * sizeof (uint32_t);
-
- for (i = 0; i < 5; i++)
- fprintf (stream, "#define composition_header_%d %d\n", i,
- ((uint32_t *) t.result)[i]);
- fprintf (stream, "static const\n");
- fprintf (stream, "struct\n");
- fprintf (stream, " {\n");
- fprintf (stream, " int level1[%zu];\n", t.level1_size);
- fprintf (stream, " short level2[%zu << %d];\n", t.level2_size, t.q);
- fprintf (stream, " unsigned int level3[%zu << %d];\n", t.level3_size, t.p);
- fprintf (stream, " }\n");
- fprintf (stream, "u_composition =\n");
- fprintf (stream, "{\n");
- fprintf (stream, " {");
- if (t.level1_size > 8)
- fprintf (stream, "\n ");
- for (i = 0; i < t.level1_size; i++)
- {
- uint32_t offset;
- if (i > 0 && (i % 8) == 0)
- fprintf (stream, "\n ");
- offset = ((uint32_t *) (t.result + level1_offset))[i];
- if (offset == 0)
- fprintf (stream, " %5d", -1);
- else
- fprintf (stream, " %5zu",
- (offset - level2_offset) / sizeof (uint32_t));
- if (i+1 < t.level1_size)
- fprintf (stream, ",");
- }
- if (t.level1_size > 8)
- fprintf (stream, "\n ");
- fprintf (stream, " },\n");
- fprintf (stream, " {");
- if (t.level2_size << t.q > 8)
- fprintf (stream, "\n ");
- for (i = 0; i < t.level2_size << t.q; i++)
- {
- uint32_t offset;
- if (i > 0 && (i % 8) == 0)
- fprintf (stream, "\n ");
- offset = ((uint32_t *) (t.result + level2_offset))[i];
- if (offset == 0)
- fprintf (stream, " %5d", -1);
- else
- fprintf (stream, " %5zu",
- (offset - level3_offset) / sizeof (uint32_t));
- if (i+1 < t.level2_size << t.q)
- fprintf (stream, ",");
- }
- if (t.level2_size << t.q > 8)
- fprintf (stream, "\n ");
- fprintf (stream, " },\n");
- fprintf (stream, " {");
- if (t.level3_size << t.p > 4)
- fprintf (stream, "\n ");
- for (i = 0; i < t.level3_size << t.p; i++)
- {
- uint32_t value = ((uint32_t *) (t.result + level3_offset))[i];
-
- if (i > 0 && (i % 4) == 0)
- fprintf (stream, "\n ");
- if (value == 0)
- fprintf (stream, " 0");
- else
- fprintf (stream, " 0x%08X", value);
- if (i+1 < t.level3_size << t.p)
- fprintf (stream, ",");
- }
- if (t.level3_size << t.p > 4)
- fprintf (stream, "\n ");
- fprintf (stream, " }\n");
- fprintf (stream, "};\n");
-
-#else
-
- /* We use gperf to implement the hash lookup, giving it the 928 sets of