Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
aliases.cpp
Go to the documentation of this file.
1
29#include <rw/_defs.h>
30
31#ifdef _RWSTD_EDG_ECCP
32 // disable error #450-D: the type "long long" is nonstandard
33 // issued for uses of the type in Linux system headers (e.g.,
34 // pthreadtypes.h)
35# pragma diag_suppress 450
36#endif // vanilla EDG eccp demo
37
38#ifdef __linux__
39 // on Linux define _XOPEN_SOURCE to get CODESET defined in <langinfo.h>
40# define _XOPEN_SOURCE 500 /* SUS conformance */
41# include <sys/types.h>
42#endif // __linux__
43
44#include "diagnostic.h"
45
46#include <cassert> // for assert()
47#include <cerrno> // for errno
48#include <cstdlib>
49#include <cstdio>
50#include <cstring> // for memcpy(), strlen()
51#include <clocale> // for setlocale()
52#include <locale> // for tolower()
53#include <iostream>
54#include <string>
55#include <vector>
56
57
58#ifndef _WIN32
59# ifndef _RWSTD_NO_NL_LANGINFO
60# include <langinfo.h>
61# endif
62#endif // _WIN32
63
64#include "aliases.h"
65
66#if __GNUG__ == 2 && __GNUC_MINOR__ == 96
67# include <unistd.h> // for close()
68
69// declare the POSIX (but not ANSI C) function mkstemp()
70extern "C" int mkstemp (char*) _LIBC_THROWS ();
71
72#endif // gcc 2.96
73
74
75struct alias_t
76{
77 const char* name; // canonical locale name
78 const char* aliases [8]; // known aliases for the name
79};
80
81
82// codesets aliases
83static const alias_t codeset_aliases [] = {
84 { "ANSI_X3.4-1968", { "ascii", "usascii", "us-ascii", "us_ascii", 0 } },
85 { "arabic8", { "arabic-8", "arabic_8", 0 } },
86 // chinese-t <=> chinese traditional
87 { "BIG5", { "big5", "chinese-t", 0 } },
88 { "BIG5-HKSCS", { "hkbig5", 0 } },
89 { "CP1251", { 0 } },
90 { "CP1255", { 0 } },
91 // !ujis is coming from Unix JIS!
92 { "EUC-JP", { "eucjp", "eucJP", "euc_jp", "euc", "ujis", 0 } },
93 { "EUC-KR", { "euckr", "eucKR", "euc_kr", 0 } },
94 { "EUC-TW", { "euctw", "eucTW", "euc_tw", "cns-11643-1992",
95 "cns11643", 0 } },
96 { "GB18030", { "gb18030", 0 } },
97 // chinese-s <=> chinese simplified
98 { "GB2312", { "gb2312", "hp15CN", "chinese-s", 0 } },
99 { "GBK", { "gbk", 0 } },
100 { "GEORGIAN-PS", { 0 } },
101 { "greek8", { "greek-8", "greek_8", 0 } },
102 { "hebrew8", { "hebrew-8", "hebrew_8", 0 } },
103 { "IS-620", { 0 } },
104
105 { "ISO-8859-1",
106 { "ISO-88591", "ISO_8859-1", "ISO8859-1", "iso88591", "iso1", 0 } },
107 { "ISO-8859-2",
108 { "ISO-88592", "ISO_8859-2", "ISO8859-2", "iso88592", "iso2", 0 } },
109 { "ISO-8859-3",
110 { "ISO-88593", "ISO_8859-3", "ISO8859-3", "iso88593", "iso3", 0 } },
111 { "ISO-8859-5",
112 { "ISO-88595", "ISO_8859-5", "ISO8859-5", "iso88595", "iso5", 0 } },
113 { "ISO-8859-6",
114 { "ISO-88596", "ISO_8859-6", "ISO8859-6", "iso88596", "iso6", 0 } },
115 { "ISO-8859-7",
116 { "ISO-88597", "ISO_8859-7", "ISO8859-7", "iso88597", "iso7",
117 "sun_eu_greek", 0 } },
118 { "ISO-8859-8",
119 { "ISO-88598", "ISO_8859-8", "ISO8859-8", "iso88598", "iso8", 0 } },
120 { "ISO-8859-9",
121 { "ISO-88599", "ISO_8859-9", "ISO8859-9", "iso88599", "iso9", 0 } },
122 { "ISO-8859-13",
123 { "ISO-885913", "ISO_8859-13", "ISO8859-13", "iso885913", "iso13", 0 } },
124 { "ISO-8859-14",
125 { "ISO-885914", "ISO_8859-14", "ISO8859-14", "iso885914", "iso14", 0 } },
126 { "ISO-8859-15",
127 { "ISO-885915", "ISO_8859-15", "ISO8859-15", "iso885915", "iso15", 0 } },
128
129 { "KOI8-R", { "koi8r", "koi8_r", 0 } },
130 { "KOI8-T", { "koi8t", "koi8_t", 0 } },
131 { "KOI8-U", { "koi8u", "koi8_u", 0 } },
132 { "PCK", { 0 } },
133 { "roman8", { "roman-8", "roman_8", 0 } },
134 { "Shift_JIS", { "shift-jis", "sjis", 0 } },
135 { "TIS-620", { "tis620", "tis620.2533", 0 } },
136 { "UTF-8", { "utf8", "utf_8", 0 } },
137 { 0, { 0 } }
138};
139
140// locale names aliases
141static const alias_t locale_aliases [] = {
142 { "af_ZA", { "afrikaans", 0 } },
143 { "ar_AE", { 0 } },
144 { "ar_BH", { 0 } },
145 { "ar_DZ", { 0 } },
146 { "ar_EG", { 0 } },
147 { "ar_IN", { 0 } },
148 { "ar_IQ", { 0 } },
149 { "ar_JO", { 0 } },
150 { "ar_KW", { 0 } },
151 { "ar_LB", { 0 } },
152 { "ar_LY", { 0 } },
153 { "ar_MA", { 0 } },
154 { "ar_OM", { 0 } },
155 { "ar_QA", { 0 } },
156 { "ar_SA", { 0 } },
157 { "ar_SD", { 0 } },
158 { "ar_SY", { 0 } },
159 { "ar_TN", { 0 } },
160 { "ar_YE", { 0 } },
161 { "be_BY", { 0 } },
162 { "bg_BG", { "bulgarian", 0 } },
163 { "br_FR", { "br", 0 } },
164 { "bs_BA", { "bs", 0 } },
165 { "ca_ES", { 0 } },
166 { "ca_ES@euro", { 0 } },
167 { "cs_CZ", { "czech", 0 } },
168 { "cy_GB", { "cy", 0 } },
169 { "da_DK", { "danish", 0 } },
170 { "de_AT", { "austrian", 0 } },
171 { "de_AT@euro", { 0 } },
172 { "de_BE", { 0 } },
173 { "de_BE@euro", { 0 } },
174 { "de_CH", { 0 } },
175 { "de_DE", { "deutsch", "german", 0 } },
176 { "de_DE@euro", { 0 } },
177 { "de_LU", { 0 } },
178 { "de_LU@euro", { 0 } },
179 { "el_GR", { "greek", 0 } },
180 { "en_AU", { 0 } },
181 { "en_BW", { 0 } },
182 { "en_CA", { 0 } },
183 { "en_DK", { 0 } },
184 { "en_GB", { 0 } },
185 { "en_HK", { 0 } },
186 { "en_IE", { 0 } },
187 { "en_IE@euro", { 0 } },
188 { "en_IN", { 0 } },
189 { "en_NZ", { 0 } },
190 { "en_PH", { 0 } },
191 { "en_SG", { 0 } },
192 { "en_US", { 0 } },
193 { "en_ZA", { 0 } },
194 { "en_ZW", { 0 } },
195 { "es_AR", { 0 } },
196 { "es_BO", { 0 } },
197 { "es_CL", { 0 } },
198 { "es_CO", { 0 } },
199 { "es_CR", { 0 } },
200 { "es_DO", { 0 } },
201 { "es_EC", { 0 } },
202 { "es_ES", { "spanish", 0 } },
203 { "es_ES@euro", { 0 } },
204 { "es_GT", { 0 } },
205 { "es_HN", { 0 } },
206 { "es_MX", { 0 } },
207 { "es_NI", { 0 } },
208 { "es_PA", { 0 } },
209 { "es_PE", { 0 } },
210 { "es_PR", { 0 } },
211 { "es_PY", { 0 } },
212 { "es_SV", { 0 } },
213 { "es_US", { 0 } },
214 { "es_UY", { 0 } },
215 { "es_VE", { 0 } },
216 { "et_EE", { "estonian", 0 } },
217 { "eu_ES", { 0 } },
218 { "eu_ES@euro", { 0 } },
219 { "fa_IR", { "fa", 0 } },
220 { "fi_FI", { "finnish", 0 } },
221 { "fi_FI@euro", { "fi", 0 } },
222 { "fo_FO", { "fo", 0 } },
223 { "fr_BE", { 0 } },
224 { "fr_BE@euro", { 0 } },
225 { "fr_CA", { "canadian", 0 } },
226 { "fr_CH", { 0 } },
227 { "fr_FR", { "french", 0 } },
228 { "fr_FR@euro", { 0 } },
229 { "fr_LU", { 0 } },
230 { "fr_LU@euro", { 0 } },
231 { "ga_IE", { 0 } },
232 { "ga_IE@euro", { 0 } },
233 { "gl_ES", { 0 } },
234 { "gl_ES@euro", { 0 } },
235 { "gv_GB", { 0 } },
236 { "he_IL", { "hebrew", 0 } },
237 { "hi_IN", { 0 } },
238 { "hr_HR", { "croatian", 0 } },
239 { "hu_HU", { "hungarian", 0 } },
240 { "id_ID", { 0 } },
241 { "is_IS", { 0 } },
242 { "it_CH", { 0 } },
243 { "it_IT", { "italian", 0 } },
244 { "it_IT@euro", { 0 } },
245 { "iw_IL", { 0 } },
246 { "ja_JP", { "ja", "japanese", 0 } },
247 { "ka_GE", { 0 } },
248 { "kl_GL", { 0 } },
249 { "ko_KR", { "ko", 0 } },
250 { "kw_GB", { 0 } },
251 { "lt_LT", { "lithuanian", 0 } },
252 { "lv_LV", { "latvian", 0 } },
253 { "mi_NZ", { 0 } },
254 { "mk_MK", { "macedonian", 0 } },
255 { "mr_IN", { 0 } },
256 { "ms_MY", { 0 } },
257 { "mt_MT", { 0 } },
258 { "nl_BE", { 0 } },
259 { "nl_BE@euro", { 0 } },
260 { "nl_NL", { "dutch", 0 } },
261 { "nl_NL@euro", { 0 } },
262 { "nn_NO", { 0 } },
263 { "no_NO", { "no", 0 } },
264 { "oc_FR", { "occitan", 0 } },
265 { "pl_PL", { "polish", 0 } },
266 { "pt_BR", { 0 } },
267 { "pt_PT", { "portuguese", 0 } },
268 { "pt_PT@euro", { 0 } },
269 { "ro_RO", { "romanian", 0 } },
270 { "ru_RU", { "russian", 0 } },
271 { "ru_UA", { 0 } },
272 { "sk_SK", { "slovakian", "slovak", 0 } },
273 { "sl_SI", { "slovenian", "sloven", 0 } },
274 { "sq_AL", { "albanian", 0 } },
275 { "sr_YU", { "serbian", 0 } },
276 { "sr_YU@cyrillic", { 0 } },
277 { "sv_FI", { 0 } },
278 { "sv_FI@euro", { 0 } },
279 { "sv_SE", { 0 } },
280 { "ta_IN", { 0 } },
281 { "te_IN", { 0 } },
282 { "tg_TJ", { 0 } },
283 { "th_TH", { "thai", 0 } },
284 { "tl_PH", { 0 } },
285 { "tr_TR", { "turkish", 0 } },
286 { "uk_UA", { "ukrainian", 0 } },
287 { "ur_PK", { 0 } },
288 { "uz_UZ", { 0 } },
289 { "vi_VN", { 0 } },
290 { "yi_US", { 0 } },
291 { "zh_TW", { "zh", "chinese", 0 } },
292 { 0, { 0 } }
293};
294
295#ifdef _WIN32
296
297struct codepage_t
298{
299 const char* name; // standard codeset name
300 unsigned int codepage; // code page number
301};
302
303static const codepage_t codepages [] = {
304 { "ANSI_X3.4-1968", 20127 },
305 { "BIG5", 950 },
306 { "GBK", 936 },
307 { "GB2312", 20936 },
308 { "ISO-8859-1", 28591 },
309 { "ISO-8859-2", 28592 },
310 { "ISO-8859-3", 28593 },
311 { "ISO-8859-4", 28594 },
312 { "ISO-8859-5", 28595 },
313 { "ISO-8859-6", 28596 },
314 { "ISO-8859-7", 28597 },
315 { "ISO-8859-8", 28598 },
316 { "ISO-8859-9", 28599 },
317 { "ISO-8859-15", 28605 },
318 { "KOI8-R", 20866 },
319 { "KOI8-U", 21866 },
320 { "Shift_JIS", 932 },
321 { "UTF-8", 65001 },
322 { 0, 0 }
323};
324
325#endif // _WIN32
326
327
328#ifdef _WIN32
329
330unsigned int get_codepage (const std::string& cname)
331{
332 for (std::size_t i = 0; codepages [i].name; i++) {
333 if (0 == ci_compare (codepages [i].name, cname.c_str ()))
334 return codepages[i].codepage;
335 }
336 return 0;
337}
338
339#endif // _WIN32
340
341
343static void store_aliases (StringVector& v, const alias_t &a)
344{
345 v.push_back (a.name);
346
347 for (std::size_t i = 0; a.aliases [i]; i++)
348 v.push_back (a.aliases [i]);
349}
350
351
353// case insensitive comparison of initial parts of the strings
354static int ci_pre_compare (const std::string& s1, const std::string& s2)
355{
356 std::string::const_iterator it1 = s1.begin ();
357 std::string::const_iterator it2 = s2.begin ();
358 for (; it1 != s1.end () && it2 != s2.end (); it1++, it2++)
359 if ( (std::tolower)(*it1, std::locale ())
360 != (std::tolower)(*it2, std::locale ()))
361 return (*it1 - *it2);
362
363 return 0;
364}
365
366
367int ci_compare (const char *s1, const char *s2)
368{
369 assert (0 != s1);
370 assert (0 != s2);
371
372 typedef unsigned char UChar;
373
374 for ( ; ; ++s1, ++s2) {
375 if (*s1 != *s2)
376 return UChar (*s1) - UChar (*s2);
377
378 if ('\0' == *s1)
379 break;
380 }
381
382 return 0;
383}
384
385// case insensitive comparison between strings
386int ci_compare (const std::string& s1, const std::string& s2)
387{
388 return ci_compare (s1.c_str (), s2.c_str ());
389}
390
391
392void get_cname_aliases (const std::string& name,
393 StringVector& aliases)
394{
395 for (std::size_t i = 0; codeset_aliases [i].name; i++) {
396 if (0 == ci_compare (codeset_aliases [i].name, name.c_str ())) {
397 // store the whole structure data
398 store_aliases (aliases, codeset_aliases [i]);
399 break;
400 }
401
402 // check the entry's aliases as well
403 for (std::size_t j = 0; codeset_aliases [i].aliases [j]; j++) {
404 if (0 == ci_compare (codeset_aliases [i].aliases [j],
405 name.c_str ())) {
406 // store the whole structure data
407 store_aliases (aliases, codeset_aliases [i]);
408 break;
409 }
410 }
411 }
412
413 if (aliases.empty ())
414 aliases.push_back (name);
415}
416
417#ifndef _WIN32
418
419void get_lname_aliases (const std::string& name,
420 StringVector& aliases)
421{
422 for (std::size_t i = 0; locale_aliases [i].name; i++) {
423 if (0 == ci_compare (locale_aliases [i].name, name.c_str ())) {
424 // store the whole structure data
425 store_aliases (aliases, locale_aliases [i]);
426 break;
427 }
428
429 // check the entry's aliases as well
430 for (std::size_t j = 0; locale_aliases [i].aliases [j]; j++) {
431 if (0 == ci_compare (locale_aliases [i].aliases [j],
432 name.c_str ())) {
433 // store the whole structure data
434 store_aliases (aliases, locale_aliases [i]);
435 break;
436 }
437 }
438 }
439
440 if (aliases.empty ())
441 aliases.push_back (name);
442}
443
444
445void get_same_encoding_C_locale (const std::string &lname,
446 const std::string &cname,
447 StringVector &libc_locales)
448{
449 // get the aliases for both name and codeset
450 StringVector la;
451 StringVector ca;
452
453 get_lname_aliases (lname, la);
454 get_cname_aliases (cname, ca);
455
456 // find all the installed C library locales that are equivalent
457 // to the locale named by `lname' and that use the encoding given
458 // by `cname'
459
460 char* locname = get_installed_locales ();
461
462 for (; *locname; locname += std::strlen (locname) + 1) {
463
464 bool match_found = false;
465
466 typedef StringVector::iterator Iterator;
467
468 // iterate through the aliases and see if any one of them
469 // starts with the same sequence
470 for (Iterator it = la.begin (); it != la.end (); ++it) {
471
472 if (0 != ci_pre_compare (locname, (*it).c_str ()))
473 continue;
474
475 // this is a good match, test to see if the encodings match
476 if (0 == std::setlocale (LC_CTYPE, locname))
477 continue;
478
479 const char* const cs = nl_langinfo (CODESET);
480
481 // compare the codeset to the aliases
482 for (Iterator it1 = ca.begin (); it1 != ca.end (); ++it1) {
483 if (0 != ci_compare (cs, (*it1).c_str ()))
484 continue;
485
486 // found a match and save it
487 libc_locales.push_back (std::string (locname));
488 match_found = true;
489 }
490
491 if (match_found)
492 break;
493 }
494 }
495}
496
497
498std::string get_C_encoding_locale (const std::string &codeset)
499{
500 // retrieve the set of aliases for this codeset
501 StringVector ca;
502 get_cname_aliases (codeset, ca);
503
504 // find a C library locale that uses the same encoding
505 char* locname = get_installed_locales ();
506
507 for (; *locname; locname += std::strlen (locname) + 1) {
508
509 // set the C locale and get the codeset name
510 if (0 == std::setlocale (LC_CTYPE, locname))
511 continue;
512
513#ifdef _RWSTD_OS_HP_UX
514
515 // skip the limited C.utf8 locale
516 if (0 == std::strcmp ("C.utf8", locname))
517 continue;
518
519#endif // _RWSTD_OS_HPUX
520
521
522 const char* const cs = nl_langinfo (CODESET);
523
524 typedef StringVector::iterator Iterator;
525
526 // compare the name with this codeset's aliases
527 for (Iterator it = ca.begin (); it != ca.end (); ++it)
528 if (0 == ci_compare (cs, (*it).c_str ())) {
529 return locname;
530 }
531 }
532
533 return std::string ();
534}
535
536
537// returns a character array consisting of NUL-separated names
538// of locales intalled on a system; if `loc_cat' is other than
539// LC_INVALID_CAT, will eliminate names that do not refer to
540// valid locales (i.e., those for which setlocale(loc_cat,
541// name) will return 0
542char* get_installed_locales (int loc_cat /* = LC_INVALID_CAT */)
543{
544 static char* slocname = 0;
545
546 static std::size_t size = 0; // number of elements in array
547 static std::size_t total_size = 5120; // the size of the array
548
549 // allocate first time through
550 if (!slocname) {
551 slocname = new char [16384];
552 *slocname = '\0';
553 }
554
555 char* locname = slocname;
556
557 // save the current locale setting and set the locale to "C"
558 const char* const save_localename = std::setlocale (LC_ALL, 0);
559 std::setlocale (LC_ALL, "C");
560
561#if __GNUG__ == 2 && __GNUC_MINOR__ == 96
562
563 // create a temporary file for the output of `locale -a'
564 char fname_buf [L_tmpnam] = "/tmp/tmpfile-XXXXXX";
565 const char *fname = fname_buf;
566
567 // avoid using tmpnam() to prevent the bogus gcc 2.96 warning:
568 // the use of `tmpnam' is dangerous, better use `mkstemp'
569 const int fd = mkstemp (fname_buf);
570
571 if (-1 == fd) {
572 std::perror ("mkstemp() failed");
573 std::abort();
574 }
575
576 close (fd);
577
578#else // if !defined (gcc 2.96)
579
580 // create a temporary file for the output of `locale -a'
581 char fname_buf [L_tmpnam];
582 const char *fname = std::tmpnam (fname_buf);
583
584#endif // gcc 2.96
585
586 if (!fname) {
587 std::perror ("tmpnam() failed");
588 std::abort ();
589 }
590
591 // create a shell command and redirect its output into the file
592
593 // cmd must be at least this large:
594 // sizeof ("locale -a | grep \"\" > ") // 22
595 // + strlen (fname) // must be <= L_tmpnam
596
597 char cmd [80 + L_tmpnam];
598
599 std::sprintf (cmd, "LC_ALL=C /usr/bin/locale -a >%s 2>/dev/null", fname);
600
601 const int ret = std::system (cmd);
602
603 if (ret)
604 issue_diag (W_NOTSUP, false, 0, "call to system(\"%s\") failed: %s\n",
605 cmd, std::strerror (errno));
606
607 // open file containing the list of installed locales
608 std::FILE *f = std::fopen (fname, "r");
609
610 if (f) {
611 // even simple locale names can be very long (e.g., on HP-UX,
612 // where a locale name always consists of the names of all
613 // categories, such as "C C C C C C")
614 char last_name [256];
615 *last_name = '\0';
616
617 // if successful, construct a char array with the locales
618 while (std::fgets (cmd, int (sizeof cmd), f)) {
619 cmd [std::strlen (cmd) - 1] = '\0';
620
621 // if our buffer is full then dynamically allocate a new one
622 if ((size += (std::strlen (cmd) + 1)) > total_size) {
623 total_size += 5120;
624 char* newBuf = new char[total_size];
625 std::memcpy (newBuf, slocname, total_size - 5120);
626 std::free (slocname);
627 slocname = newBuf;
628 locname = slocname + size - std::strlen (cmd) - 1;
629 }
630
631#ifdef _WIN64
632
633 // prevent a hang (OS/libc bug?)
634 std::strcpy (locname, cmd);
635 locname += std::strlen (cmd) + 1;
636
637#else
638
639 if (loc_cat != int (LC_INVALID_CAT)) {
640
641 // set the C locale to verify that the name is valid
642 const char *name = std::setlocale (loc_cat, cmd);
643
644 // if it is and if the actual locale name different
645 // from the last one, append it to the list
646 if (name && std::strcmp (last_name, name)) {
647 std::strcpy (locname, cmd);
648 locname += std::strlen (cmd) + 1;
649
650 // save the last locale name
651 assert (std::strlen (name) < sizeof last_name);
652 std::strcpy (last_name, name);
653 }
654 }
655 else {
656 std::strcpy (locname, cmd);
657 locname += std::strlen (cmd) + 1;
658 }
659
660#endif // _WIN64
661
662 }
663 *locname = '\0';
664
665 }
666
667 // restore the original locale
668 if (save_localename)
669 std::setlocale (LC_ALL, save_localename);
670
671 std::fclose (f);
672 std::remove (fname);
673 return slocname;
674}
675
676#endif // _WIN32
InputIter< UserClass > Iterator
#define i
Definition 17.names.cpp:126
#define s1
Definition 17.names.cpp:242
#define v
Definition 17.names.cpp:138
#define s2
Definition 17.names.cpp:268
#define f
Definition 17.names.cpp:119
#define a
Definition 17.names.cpp:109
#define j
Definition 17.names.cpp:127
#define close(f)
#define assert(expr)
Definition _cassert.h:40
#define LC_CTYPE
#define LC_ALL
#define L_tmpnam
#define _LIBC_THROWS()
Definition _defs.h:1152
char * get_installed_locales(int loc_cat)
Definition aliases.cpp:542
void get_lname_aliases(const std::string &name, StringVector &aliases)
Definition aliases.cpp:419
void get_same_encoding_C_locale(const std::string &lname, const std::string &cname, StringVector &libc_locales)
Definition aliases.cpp:445
void get_cname_aliases(const std::string &name, StringVector &aliases)
Definition aliases.cpp:392
int ci_compare(const char *s1, const char *s2)
Definition aliases.cpp:367
std::string get_C_encoding_locale(const std::string &codeset)
Definition aliases.cpp:498
#define LC_INVALID_CAT
Definition aliases.h:59
std::vector< std::string > StringVector
Definition aliases.h:43
unsigned int get_codepage(const std::string &)
const char * name
Definition codecvt1.cpp:72
bool issue_diag(int type, bool, const Scanner::token_t *token, const char *fmt,...)
@ W_NOTSUP
Definition diagnostic.h:76
unsigned char UChar
Definition collate.cpp:122
const char * name
Definition aliases.cpp:77
const char * aliases[8]
Definition aliases.cpp:78
int mkstemp(char *)