1c3d31fe1Smrg /* Make ucnid.h from various sources.
2*dd083157Smrg Copyright (C) 2005-2020 Free Software Foundation, Inc.
3c3d31fe1Smrg
4c3d31fe1Smrg This program is free software; you can redistribute it and/or modify it
5c3d31fe1Smrg under the terms of the GNU General Public License as published by the
6c3d31fe1Smrg Free Software Foundation; either version 3, or (at your option) any
7c3d31fe1Smrg later version.
8c3d31fe1Smrg
9c3d31fe1Smrg This program is distributed in the hope that it will be useful,
10c3d31fe1Smrg but WITHOUT ANY WARRANTY; without even the implied warranty of
11c3d31fe1Smrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12c3d31fe1Smrg GNU General Public License for more details.
13c3d31fe1Smrg
14c3d31fe1Smrg You should have received a copy of the GNU General Public License
15c3d31fe1Smrg along with this program; see the file COPYING3. If not see
16c3d31fe1Smrg <http://www.gnu.org/licenses/>. */
17c3d31fe1Smrg
18c3d31fe1Smrg /* Run this program as
19c3d31fe1Smrg ./makeucnid ucnid.tab UnicodeData.txt DerivedNormalizationProps.txt \
20c3d31fe1Smrg > ucnid.h
21c3d31fe1Smrg */
22c3d31fe1Smrg
23c3d31fe1Smrg #include <stdio.h>
24c3d31fe1Smrg #include <string.h>
25c3d31fe1Smrg #include <ctype.h>
26c3d31fe1Smrg #include <stdbool.h>
27c3d31fe1Smrg #include <stdlib.h>
28c3d31fe1Smrg
29c3d31fe1Smrg enum {
30c3d31fe1Smrg C99 = 1,
31c3d31fe1Smrg CXX = 2,
325ef59e75Smrg N99 = 4,
335ef59e75Smrg C11 = 8,
345ef59e75Smrg N11 = 16,
355ef59e75Smrg all_languages = C99 | CXX | C11,
365ef59e75Smrg not_NFC = 32,
375ef59e75Smrg not_NFKC = 64,
385ef59e75Smrg maybe_not_NFC = 128
39c3d31fe1Smrg };
40c3d31fe1Smrg
415ef59e75Smrg #define NUM_CODE_POINTS 0x110000
425ef59e75Smrg #define MAX_CODE_POINT 0x10ffff
435ef59e75Smrg
445ef59e75Smrg static unsigned flags[NUM_CODE_POINTS];
455ef59e75Smrg static unsigned int all_decomp[NUM_CODE_POINTS][2];
465ef59e75Smrg static unsigned int decomp[NUM_CODE_POINTS][2];
475ef59e75Smrg static unsigned char combining_value[NUM_CODE_POINTS];
48c3d31fe1Smrg
49c3d31fe1Smrg /* Die! */
50c3d31fe1Smrg
51c3d31fe1Smrg static void
fail(const char * s)52c3d31fe1Smrg fail (const char *s)
53c3d31fe1Smrg {
54c3d31fe1Smrg fprintf (stderr, "%s\n", s);
55c3d31fe1Smrg exit (1);
56c3d31fe1Smrg }
57c3d31fe1Smrg
585ef59e75Smrg /* Read ucnid.tab and set the flags for language versions in header[]. */
59c3d31fe1Smrg
60c3d31fe1Smrg static void
read_ucnid(const char * fname)61c3d31fe1Smrg read_ucnid (const char *fname)
62c3d31fe1Smrg {
63c3d31fe1Smrg FILE *f = fopen (fname, "r");
64c3d31fe1Smrg unsigned fl = 0;
65c3d31fe1Smrg
66c3d31fe1Smrg if (!f)
67c3d31fe1Smrg fail ("opening ucnid.tab");
68c3d31fe1Smrg for (;;)
69c3d31fe1Smrg {
70c3d31fe1Smrg char line[256];
71c3d31fe1Smrg
72c3d31fe1Smrg if (!fgets (line, sizeof (line), f))
73c3d31fe1Smrg break;
74c3d31fe1Smrg if (strcmp (line, "[C99]\n") == 0)
75c3d31fe1Smrg fl = C99;
765ef59e75Smrg else if (strcmp (line, "[C99DIG]\n") == 0)
775ef59e75Smrg fl = C99|N99;
78c3d31fe1Smrg else if (strcmp (line, "[CXX]\n") == 0)
79c3d31fe1Smrg fl = CXX;
805ef59e75Smrg else if (strcmp (line, "[C11]\n") == 0)
815ef59e75Smrg fl = C11;
825ef59e75Smrg else if (strcmp (line, "[C11NOSTART]\n") == 0)
835ef59e75Smrg fl = C11|N11;
84c3d31fe1Smrg else if (isxdigit (line[0]))
85c3d31fe1Smrg {
86c3d31fe1Smrg char *l = line;
87c3d31fe1Smrg while (*l)
88c3d31fe1Smrg {
89c3d31fe1Smrg unsigned long start, end;
90c3d31fe1Smrg char *endptr;
91c3d31fe1Smrg start = strtoul (l, &endptr, 16);
92c3d31fe1Smrg if (endptr == l || (*endptr != '-' && ! isspace (*endptr)))
93c3d31fe1Smrg fail ("parsing ucnid.tab [1]");
94c3d31fe1Smrg l = endptr;
95c3d31fe1Smrg if (*l != '-')
96c3d31fe1Smrg end = start;
97c3d31fe1Smrg else
98c3d31fe1Smrg {
99c3d31fe1Smrg end = strtoul (l + 1, &endptr, 16);
100c3d31fe1Smrg if (end < start)
101c3d31fe1Smrg fail ("parsing ucnid.tab, end before start");
102c3d31fe1Smrg l = endptr;
103c3d31fe1Smrg if (! isspace (*l))
104c3d31fe1Smrg fail ("parsing ucnid.tab, junk after range");
105c3d31fe1Smrg }
106c3d31fe1Smrg while (isspace (*l))
107c3d31fe1Smrg l++;
1085ef59e75Smrg if (end > MAX_CODE_POINT)
109c3d31fe1Smrg fail ("parsing ucnid.tab, end too large");
110c3d31fe1Smrg while (start <= end)
111c3d31fe1Smrg flags[start++] |= fl;
112c3d31fe1Smrg }
113c3d31fe1Smrg }
114c3d31fe1Smrg }
115c3d31fe1Smrg if (ferror (f))
116c3d31fe1Smrg fail ("reading ucnid.tab");
117c3d31fe1Smrg fclose (f);
118c3d31fe1Smrg }
119c3d31fe1Smrg
1205ef59e75Smrg /* Read UnicodeData.txt and fill in the 'decomp' table to be the
1215ef59e75Smrg decompositions of characters for which both the character
1225ef59e75Smrg decomposed and all the code points in the decomposition are valid
1235ef59e75Smrg for some supported language version, and the 'all_decomp' table to
1245ef59e75Smrg be the decompositions of all characters without those
1255ef59e75Smrg constraints. */
126c3d31fe1Smrg
127c3d31fe1Smrg static void
read_table(char * fname)128c3d31fe1Smrg read_table (char *fname)
129c3d31fe1Smrg {
130c3d31fe1Smrg FILE * f = fopen (fname, "r");
131c3d31fe1Smrg
132c3d31fe1Smrg if (!f)
133c3d31fe1Smrg fail ("opening UnicodeData.txt");
134c3d31fe1Smrg for (;;)
135c3d31fe1Smrg {
136c3d31fe1Smrg char line[256];
137c3d31fe1Smrg unsigned long codepoint, this_decomp[4];
138c3d31fe1Smrg char *l;
1395ef59e75Smrg int i, j;
140c3d31fe1Smrg int decomp_useful;
141c3d31fe1Smrg
142c3d31fe1Smrg if (!fgets (line, sizeof (line), f))
143c3d31fe1Smrg break;
144c3d31fe1Smrg codepoint = strtoul (line, &l, 16);
145c3d31fe1Smrg if (l == line || *l != ';')
146c3d31fe1Smrg fail ("parsing UnicodeData.txt, reading code point");
1475ef59e75Smrg if (codepoint > MAX_CODE_POINT)
1485ef59e75Smrg fail ("parsing UnicodeData.txt, code point too large");
149c3d31fe1Smrg
150c3d31fe1Smrg do {
151c3d31fe1Smrg l++;
152c3d31fe1Smrg } while (*l != ';');
1535ef59e75Smrg /* Category value. */
154c3d31fe1Smrg do {
155c3d31fe1Smrg l++;
156c3d31fe1Smrg } while (*l != ';');
157c3d31fe1Smrg /* Canonical combining class; in NFC/NFKC, they must be increasing
158c3d31fe1Smrg (or zero). */
159c3d31fe1Smrg if (! isdigit (*++l))
160c3d31fe1Smrg fail ("parsing UnicodeData.txt, combining class not number");
161c3d31fe1Smrg combining_value[codepoint] = strtoul (l, &l, 10);
162c3d31fe1Smrg if (*l++ != ';')
163c3d31fe1Smrg fail ("parsing UnicodeData.txt, junk after combining class");
164c3d31fe1Smrg
165c3d31fe1Smrg /* Skip over bidi value. */
166c3d31fe1Smrg do {
167c3d31fe1Smrg l++;
168c3d31fe1Smrg } while (*l != ';');
169c3d31fe1Smrg
170c3d31fe1Smrg /* Decomposition mapping. */
171c3d31fe1Smrg decomp_useful = flags[codepoint];
172c3d31fe1Smrg if (*++l == '<') /* Compatibility mapping. */
173c3d31fe1Smrg continue;
174c3d31fe1Smrg for (i = 0; i < 4; i++)
175c3d31fe1Smrg {
176c3d31fe1Smrg if (*l == ';')
177c3d31fe1Smrg break;
178c3d31fe1Smrg if (!isxdigit (*l))
179c3d31fe1Smrg fail ("parsing UnicodeData.txt, decomposition format");
180c3d31fe1Smrg this_decomp[i] = strtoul (l, &l, 16);
181c3d31fe1Smrg decomp_useful &= flags[this_decomp[i]];
182c3d31fe1Smrg while (isspace (*l))
183c3d31fe1Smrg l++;
184c3d31fe1Smrg }
185c3d31fe1Smrg if (i > 2) /* Decomposition too long. */
186c3d31fe1Smrg fail ("parsing UnicodeData.txt, decomposition too long");
1875ef59e75Smrg for (j = 0; j < i; j++)
1885ef59e75Smrg all_decomp[codepoint][j] = this_decomp[j];
1895ef59e75Smrg if ((flags[codepoint] & all_languages) && decomp_useful)
190c3d31fe1Smrg while (--i >= 0)
191c3d31fe1Smrg decomp[codepoint][i] = this_decomp[i];
192c3d31fe1Smrg }
193c3d31fe1Smrg if (ferror (f))
194c3d31fe1Smrg fail ("reading UnicodeData.txt");
195c3d31fe1Smrg fclose (f);
196c3d31fe1Smrg }
197c3d31fe1Smrg
198c3d31fe1Smrg /* Read DerivedNormalizationProps.txt and set the flags that say whether
199c3d31fe1Smrg a character is in NFC, NFKC, or is context-dependent. */
200c3d31fe1Smrg
201c3d31fe1Smrg static void
read_derived(const char * fname)202c3d31fe1Smrg read_derived (const char *fname)
203c3d31fe1Smrg {
204c3d31fe1Smrg FILE * f = fopen (fname, "r");
205c3d31fe1Smrg
206c3d31fe1Smrg if (!f)
207c3d31fe1Smrg fail ("opening DerivedNormalizationProps.txt");
208c3d31fe1Smrg for (;;)
209c3d31fe1Smrg {
210c3d31fe1Smrg char line[256];
211c3d31fe1Smrg unsigned long start, end;
212c3d31fe1Smrg char *l;
213c3d31fe1Smrg bool not_NFC_p, not_NFKC_p, maybe_not_NFC_p;
214c3d31fe1Smrg
215c3d31fe1Smrg if (!fgets (line, sizeof (line), f))
216c3d31fe1Smrg break;
217c3d31fe1Smrg not_NFC_p = (strstr (line, "; NFC_QC; N") != NULL);
218c3d31fe1Smrg not_NFKC_p = (strstr (line, "; NFKC_QC; N") != NULL);
219c3d31fe1Smrg maybe_not_NFC_p = (strstr (line, "; NFC_QC; M") != NULL);
220c3d31fe1Smrg if (! not_NFC_p && ! not_NFKC_p && ! maybe_not_NFC_p)
221c3d31fe1Smrg continue;
222c3d31fe1Smrg
223c3d31fe1Smrg start = strtoul (line, &l, 16);
224c3d31fe1Smrg if (l == line)
225c3d31fe1Smrg fail ("parsing DerivedNormalizationProps.txt, reading start");
2265ef59e75Smrg if (start > MAX_CODE_POINT)
2275ef59e75Smrg fail ("parsing DerivedNormalizationProps.txt, code point too large");
228c3d31fe1Smrg if (*l == '.' && l[1] == '.')
229c3d31fe1Smrg end = strtoul (l + 2, &l, 16);
230c3d31fe1Smrg else
231c3d31fe1Smrg end = start;
232c3d31fe1Smrg
233c3d31fe1Smrg while (start <= end)
234c3d31fe1Smrg flags[start++] |= ((not_NFC_p ? not_NFC : 0)
235c3d31fe1Smrg | (not_NFKC_p ? not_NFKC : 0)
236c3d31fe1Smrg | (maybe_not_NFC_p ? maybe_not_NFC : 0)
237c3d31fe1Smrg );
238c3d31fe1Smrg }
239c3d31fe1Smrg if (ferror (f))
240c3d31fe1Smrg fail ("reading DerivedNormalizationProps.txt");
241c3d31fe1Smrg fclose (f);
242c3d31fe1Smrg }
243c3d31fe1Smrg
244c3d31fe1Smrg /* Write out the table.
245c3d31fe1Smrg The table consists of two words per entry. The first word is the flags
246c3d31fe1Smrg for the unicode code points up to and including the second word. */
247c3d31fe1Smrg
248c3d31fe1Smrg static void
write_table(void)249c3d31fe1Smrg write_table (void)
250c3d31fe1Smrg {
251c3d31fe1Smrg unsigned i;
252c3d31fe1Smrg unsigned last_flag = flags[0];
253c3d31fe1Smrg bool really_safe = decomp[0][0] == 0;
254c3d31fe1Smrg unsigned char last_combine = combining_value[0];
255c3d31fe1Smrg
2565ef59e75Smrg printf ("static const struct ucnrange ucnranges[] = {\n");
2575ef59e75Smrg
2585ef59e75Smrg for (i = 1; i <= NUM_CODE_POINTS; i++)
2595ef59e75Smrg if (i == NUM_CODE_POINTS
2605ef59e75Smrg || (flags[i] != last_flag && ((flags[i] | last_flag) & all_languages))
261c3d31fe1Smrg || really_safe != (decomp[i][0] == 0)
262c3d31fe1Smrg || combining_value[i] != last_combine)
263c3d31fe1Smrg {
2645ef59e75Smrg printf ("{ %s|%s|%s|%s|%s|%s|%s|%s|%s, %3d, %#06x },\n",
265c3d31fe1Smrg last_flag & C99 ? "C99" : " 0",
2665ef59e75Smrg last_flag & N99 ? "N99" : " 0",
267c3d31fe1Smrg last_flag & CXX ? "CXX" : " 0",
2685ef59e75Smrg last_flag & C11 ? "C11" : " 0",
2695ef59e75Smrg last_flag & N11 ? "N11" : " 0",
270c3d31fe1Smrg really_safe ? "CID" : " 0",
271c3d31fe1Smrg last_flag & not_NFC ? " 0" : "NFC",
272c3d31fe1Smrg last_flag & not_NFKC ? " 0" : "NKC",
273c3d31fe1Smrg last_flag & maybe_not_NFC ? "CTX" : " 0",
274c3d31fe1Smrg combining_value[i - 1],
275c3d31fe1Smrg i - 1);
276c3d31fe1Smrg last_flag = flags[i];
277c3d31fe1Smrg last_combine = combining_value[0];
278c3d31fe1Smrg really_safe = decomp[i][0] == 0;
279c3d31fe1Smrg }
2805ef59e75Smrg
2815ef59e75Smrg printf ("};\n");
2825ef59e75Smrg }
2835ef59e75Smrg
2845ef59e75Smrg /* Return whether a given character is valid in an identifier for some
2855ef59e75Smrg supported language, either as itself or as a UCN. */
2865ef59e75Smrg
2875ef59e75Smrg static bool
char_id_valid(unsigned int c)2885ef59e75Smrg char_id_valid (unsigned int c)
2895ef59e75Smrg {
2905ef59e75Smrg return ((flags[c] & all_languages)
2915ef59e75Smrg || (c == 0x24)
2925ef59e75Smrg || (c >= 0x30 && c <= 0x39)
2935ef59e75Smrg || (c >= 0x41 && c <= 0x5a)
2945ef59e75Smrg || (c >= 0x61 && c <= 0x7a));
2955ef59e75Smrg }
2965ef59e75Smrg
2975ef59e75Smrg /* Write out the switch statement over characters for which it is
2985ef59e75Smrg context-dependent whether they are in NFC. */
2995ef59e75Smrg
3005ef59e75Smrg static void
write_context_switch(void)3015ef59e75Smrg write_context_switch (void)
3025ef59e75Smrg {
3035ef59e75Smrg unsigned i;
3045ef59e75Smrg printf ("static bool\n"
3055ef59e75Smrg "check_nfc (cpp_reader *pfile, cppchar_t c, cppchar_t p)\n"
3065ef59e75Smrg "{\n"
3075ef59e75Smrg " switch (c)\n"
3085ef59e75Smrg " {\n");
3095ef59e75Smrg for (i = 0; i < NUM_CODE_POINTS; i++)
3105ef59e75Smrg {
3115ef59e75Smrg bool found_case = false;
3125ef59e75Smrg unsigned j;
3135ef59e75Smrg if (!(flags[i] & all_languages) || !(flags[i] & maybe_not_NFC))
3145ef59e75Smrg continue;
3155ef59e75Smrg if ((i >= 0x1161 && i <= 0x1175) || (i >= 0x11A8 && i <= 0x11C2))
3165ef59e75Smrg continue; /* Hangul handled algorithmically. */
3175ef59e75Smrg printf (" case %#06x:\n"
3185ef59e75Smrg " switch (p)\n"
3195ef59e75Smrg "\t{\n", i);
3205ef59e75Smrg /* If an NFC starter character decomposes with this character I
3215ef59e75Smrg as the second character and an NFC starter character S as the
3225ef59e75Smrg first character, that latter character as a previous
3235ef59e75Smrg character means this character is not NFC. Furthermore, any
3245ef59e75Smrg NFC starter character K made by a series of compositions of S
3255ef59e75Smrg with combining characters whose combining class is greater
3265ef59e75Smrg than that of I also means this character is not NFC. */
3275ef59e75Smrg for (j = 0; j < NUM_CODE_POINTS; j++)
3285ef59e75Smrg {
3295ef59e75Smrg unsigned s, k;
3305ef59e75Smrg if (all_decomp[j][1] != i)
3315ef59e75Smrg continue;
3325ef59e75Smrg s = all_decomp[j][0];
3335ef59e75Smrg if (combining_value[s] != 0 || (flags[s] & not_NFC) != 0)
3345ef59e75Smrg continue;
3355ef59e75Smrg if (char_id_valid (s))
3365ef59e75Smrg {
3375ef59e75Smrg found_case = true;
3385ef59e75Smrg printf ("\tcase %#06x:\n", s);
3395ef59e75Smrg }
3405ef59e75Smrg for (k = 0; k < NUM_CODE_POINTS; k++)
3415ef59e75Smrg {
3425ef59e75Smrg unsigned t = k;
3435ef59e75Smrg if (k == s || !char_id_valid (k))
3445ef59e75Smrg continue;
3455ef59e75Smrg while (all_decomp[t][1] != 0
3465ef59e75Smrg && combining_value[all_decomp[t][1]] > combining_value[i])
3475ef59e75Smrg {
3485ef59e75Smrg if (combining_value[t] != 0 || (flags[t] & not_NFC) != 0)
3495ef59e75Smrg break;
3505ef59e75Smrg t = all_decomp[t][0];
3515ef59e75Smrg }
3525ef59e75Smrg if (t == s)
3535ef59e75Smrg {
3545ef59e75Smrg found_case = true;
3555ef59e75Smrg printf ("\tcase %#06x:\n", k);
3565ef59e75Smrg }
3575ef59e75Smrg }
3585ef59e75Smrg }
3595ef59e75Smrg if (found_case)
3605ef59e75Smrg printf ("\t return false;\n");
3615ef59e75Smrg else
3625ef59e75Smrg printf ("\t/* Non-NFC cases not applicable to C/C++. */\n");
3635ef59e75Smrg printf ("\tdefault:\n"
3645ef59e75Smrg "\t return true;\n"
3655ef59e75Smrg "\t}\n\n");
3665ef59e75Smrg }
3675ef59e75Smrg printf (" default:\n"
3685ef59e75Smrg " cpp_error (pfile, CPP_DL_ICE, \"Character %%x might not be NFKC\", c);\n"
3695ef59e75Smrg " return true;\n"
3705ef59e75Smrg " }\n"
3715ef59e75Smrg "}\n");
372c3d31fe1Smrg }
373c3d31fe1Smrg
374c3d31fe1Smrg /* Print out the huge copyright notice. */
375c3d31fe1Smrg
376c3d31fe1Smrg static void
write_copyright(void)377c3d31fe1Smrg write_copyright (void)
378c3d31fe1Smrg {
379c3d31fe1Smrg static const char copyright[] = "\
380c3d31fe1Smrg /* Unicode characters and various properties.\n\
381*dd083157Smrg Copyright (C) 2003-2020 Free Software Foundation, Inc.\n\
382c3d31fe1Smrg \n\
383c3d31fe1Smrg This program is free software; you can redistribute it and/or modify it\n\
384c3d31fe1Smrg under the terms of the GNU General Public License as published by the\n\
385c3d31fe1Smrg Free Software Foundation; either version 3, or (at your option) any\n\
386c3d31fe1Smrg later version.\n\
387c3d31fe1Smrg \n\
388c3d31fe1Smrg This program is distributed in the hope that it will be useful,\n\
389c3d31fe1Smrg but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
390c3d31fe1Smrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
391c3d31fe1Smrg GNU General Public License for more details.\n\
392c3d31fe1Smrg \n\
393c3d31fe1Smrg You should have received a copy of the GNU General Public License\n\
394c3d31fe1Smrg along with this program; see the file COPYING3. If not see\n\
395c3d31fe1Smrg <http://www.gnu.org/licenses/>.\n\
396c3d31fe1Smrg \n\
397c3d31fe1Smrg \n\
398c3d31fe1Smrg Copyright (C) 1991-2005 Unicode, Inc. All rights reserved.\n\
399c3d31fe1Smrg Distributed under the Terms of Use in\n\
400c3d31fe1Smrg http://www.unicode.org/copyright.html.\n\
401c3d31fe1Smrg \n\
402c3d31fe1Smrg Permission is hereby granted, free of charge, to any person\n\
403c3d31fe1Smrg obtaining a copy of the Unicode data files and any associated\n\
404c3d31fe1Smrg documentation (the \"Data Files\") or Unicode software and any\n\
405c3d31fe1Smrg associated documentation (the \"Software\") to deal in the Data Files\n\
406c3d31fe1Smrg or Software without restriction, including without limitation the\n\
407c3d31fe1Smrg rights to use, copy, modify, merge, publish, distribute, and/or\n\
408c3d31fe1Smrg sell copies of the Data Files or Software, and to permit persons to\n\
409c3d31fe1Smrg whom the Data Files or Software are furnished to do so, provided\n\
410c3d31fe1Smrg that (a) the above copyright notice(s) and this permission notice\n\
411c3d31fe1Smrg appear with all copies of the Data Files or Software, (b) both the\n\
412c3d31fe1Smrg above copyright notice(s) and this permission notice appear in\n\
413c3d31fe1Smrg associated documentation, and (c) there is clear notice in each\n\
414c3d31fe1Smrg modified Data File or in the Software as well as in the\n\
415c3d31fe1Smrg documentation associated with the Data File(s) or Software that the\n\
416c3d31fe1Smrg data or software has been modified.\n\
417c3d31fe1Smrg \n\
418c3d31fe1Smrg THE DATA FILES AND SOFTWARE ARE PROVIDED \"AS IS\", WITHOUT WARRANTY\n\
419c3d31fe1Smrg OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\n\
420c3d31fe1Smrg WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n\
421c3d31fe1Smrg NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE\n\
422c3d31fe1Smrg COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR\n\
423c3d31fe1Smrg ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY\n\
424c3d31fe1Smrg DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,\n\
425c3d31fe1Smrg WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\n\
426c3d31fe1Smrg ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE\n\
427c3d31fe1Smrg OF THE DATA FILES OR SOFTWARE.\n\
428c3d31fe1Smrg \n\
429c3d31fe1Smrg Except as contained in this notice, the name of a copyright holder\n\
430c3d31fe1Smrg shall not be used in advertising or otherwise to promote the sale,\n\
431c3d31fe1Smrg use or other dealings in these Data Files or Software without prior\n\
432c3d31fe1Smrg written authorization of the copyright holder. */\n";
433c3d31fe1Smrg
434c3d31fe1Smrg puts (copyright);
435c3d31fe1Smrg }
436c3d31fe1Smrg
437c3d31fe1Smrg /* Main program. */
438c3d31fe1Smrg
439c3d31fe1Smrg int
main(int argc,char ** argv)440c3d31fe1Smrg main(int argc, char ** argv)
441c3d31fe1Smrg {
442c3d31fe1Smrg if (argc != 4)
443c3d31fe1Smrg fail ("too few arguments to makeucn");
444c3d31fe1Smrg read_ucnid (argv[1]);
445c3d31fe1Smrg read_table (argv[2]);
446c3d31fe1Smrg read_derived (argv[3]);
447c3d31fe1Smrg
448c3d31fe1Smrg write_copyright ();
449c3d31fe1Smrg write_table ();
4505ef59e75Smrg write_context_switch ();
451c3d31fe1Smrg return 0;
452c3d31fe1Smrg }
453