X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Fliblunicode%2Fucdata%2Fucdata.c;h=77e32a3a3cceaf62771029e24b15de22cbc923bf;hb=b6bbc69e2f8d3f27b87f7448828a7d4f632214c9;hp=29f97bd70816b7760a7b29e408917db8a827d066;hpb=fe98d9fa7b313ffe51f09ea175e5126200793bcd;p=openldap diff --git a/libraries/liblunicode/ucdata/ucdata.c b/libraries/liblunicode/ucdata/ucdata.c index 29f97bd708..77e32a3a3c 100644 --- a/libraries/liblunicode/ucdata/ucdata.c +++ b/libraries/liblunicode/ucdata/ucdata.c @@ -1,5 +1,10 @@ +/* $OpenLDAP$ */ /* - * Copyright 1999 Computing Research Labs, New Mexico State University + * Copyright 2000-2002 The OpenLDAP Foundation, All Rights Reserved. + * COPYING RESTRICTIONS APPLY, see COPYRIGHT file + */ +/* + * Copyright 2001 Computing Research Labs, New Mexico State University * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -19,20 +24,17 @@ * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef lint -#ifdef __GNUC__ -static char rcsid[] __attribute__ ((unused)) = "$Id: ucdata.c,v 1.3 1999/08/23 16:14:09 mleisher Exp $"; -#else -static char rcsid[] = "$Id: ucdata.c,v 1.3 1999/08/23 16:14:09 mleisher Exp $"; -#endif -#endif +/* $Id: ucdata.c,v 1.4 2001/01/02 18:46:20 mleisher Exp $" */ + +#include "portable.h" +#include "ldap_config.h" #include -#include -#include -#ifndef WIN32 -#include -#endif +#include +#include +#include +#include + #include "ucdata.h" @@ -43,11 +45,11 @@ static char rcsid[] = "$Id: ucdata.c,v 1.3 1999/08/23 16:14:09 mleisher Exp $"; **************************************************************************/ typedef struct { - unsigned short bom; - unsigned short cnt; + ac_uint4 bom; + ac_uint4 cnt; union { - unsigned long bytes; - unsigned short len[2]; + ac_uint4 bytes; + ac_uint2 len[2]; } size; } _ucheader_t; @@ -55,12 +57,14 @@ typedef struct { * A simple array of 32-bit masks for lookup. */ static unsigned long masks32[32] = { - 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020, - 0x00000040, 0x00000080, 0x00000100, 0x00000200, 0x00000400, 0x00000800, - 0x00001000, 0x00002000, 0x00004000, 0x00008000, 0x00010000, 0x00020000, - 0x00040000, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00800000, - 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, - 0x40000000, 0x80000000 + 0x00000001UL, 0x00000002UL, 0x00000004UL, 0x00000008UL, + 0x00000010UL, 0x00000020UL, 0x00000040UL, 0x00000080UL, + 0x00000100UL, 0x00000200UL, 0x00000400UL, 0x00000800UL, + 0x00001000UL, 0x00002000UL, 0x00004000UL, 0x00008000UL, + 0x00010000UL, 0x00020000UL, 0x00040000UL, 0x00080000UL, + 0x00100000UL, 0x00200000UL, 0x00400000UL, 0x00800000UL, + 0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL, + 0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL }; #define endian_short(cc) (((cc) >> 8) | (((cc) & 0xff) << 8)) @@ -68,12 +72,7 @@ static unsigned long masks32[32] = { ((((cc) >> 16) & 0xff) << 8)|((cc) >> 24)) static FILE * -#ifdef __STDC__ _ucopenfile(char *paths, char *filename, char *mode) -#else -_ucopenfile(paths, filename, mode) -char *paths, *filename, *mode; -#endif { FILE *f; char *fp, *dp, *pp, path[BUFSIZ]; @@ -86,7 +85,7 @@ char *paths, *filename, *mode; pp = path; while (*dp && *dp != ':') *pp++ = *dp++; - *pp++ = '/'; + *pp++ = *LDAP_DIRSEP; fp = filename; while (*fp) @@ -113,14 +112,11 @@ static unsigned long _ucprop_size; static unsigned short *_ucprop_offsets; static unsigned long *_ucprop_ranges; -static void -#ifdef __STDC__ +/* + * Return -1 on error, 0 if okay + */ +static int _ucprop_load(char *paths, int reload) -#else -_ucprop_load(paths, reload) -char *paths; -int reload; -#endif { FILE *in; unsigned long size, i; @@ -131,7 +127,7 @@ int reload; /* * The character properties have already been loaded. */ - return; + return 0; /* * Unload the current character property data in preparation for @@ -144,7 +140,7 @@ int reload; } if ((in = _ucopenfile(paths, "ctype.dat", "rb")) == 0) - return; + return -1; /* * Load the header. @@ -158,7 +154,7 @@ int reload; if ((_ucprop_size = hdr.cnt) == 0) { fclose(in); - return; + return -1; } /* @@ -207,14 +203,11 @@ int reload; for (i = 0; i < _ucprop_offsets[_ucprop_size]; i++) _ucprop_ranges[i] = endian_long(_ucprop_ranges[i]); } + return 0; } static void -#ifdef __STDC__ _ucprop_unload(void) -#else -_ucprop_unload() -#endif { if (_ucprop_size == 0) return; @@ -228,15 +221,13 @@ _ucprop_unload() } static int -#ifdef __STDC__ _ucprop_lookup(unsigned long code, unsigned long n) -#else -_ucprop_lookup(code, n) -unsigned long code, n; -#endif { long l, r, m; + if (_ucprop_size == 0) + return 0; + /* * There is an extra node on the end of the offsets to allow this routine * to work right. If the index is 0xffff, then there are no nodes for the @@ -272,12 +263,7 @@ unsigned long code, n; } int -#ifdef __STDC__ ucisprop(unsigned long code, unsigned long mask1, unsigned long mask2) -#else -ucisprop(code, mask1, mask2) -unsigned long code, mask1, mask2; -#endif { unsigned long i; @@ -307,14 +293,11 @@ static unsigned long _uccase_size; static unsigned short _uccase_len[2]; static unsigned long *_uccase_map; -static void -#ifdef __STDC__ +/* + * Return -1 on error, 0 if okay + */ +static int _uccase_load(char *paths, int reload) -#else -_uccase_load(paths, reload) -char *paths; -int reload; -#endif { FILE *in; unsigned long i; @@ -325,14 +308,14 @@ int reload; /* * The case mappings have already been loaded. */ - return; + return 0; free((char *) _uccase_map); _uccase_size = 0; } if ((in = _ucopenfile(paths, "case.dat", "rb")) == 0) - return; + return -1; /* * Load the header. @@ -368,14 +351,12 @@ int reload; for (i = 0; i < _uccase_size; i++) _uccase_map[i] = endian_long(_uccase_map[i]); } + fclose(in); + return 0; } static void -#ifdef __STDC__ _uccase_unload(void) -#else -_uccase_unload() -#endif { if (_uccase_size == 0) return; @@ -385,14 +366,7 @@ _uccase_unload() } static unsigned long -#ifdef __STDC__ _uccase_lookup(unsigned long code, long l, long r, int field) -#else -_uccase_lookup(code, l, r, field) -unsigned long code; -long l, r; -int field; -#endif { long m; @@ -418,12 +392,7 @@ int field; } unsigned long -#ifdef __STDC__ uctoupper(unsigned long code) -#else -uctoupper(code) -unsigned long code; -#endif { int field; long l, r; @@ -450,12 +419,7 @@ unsigned long code; } unsigned long -#ifdef __STDC__ uctolower(unsigned long code) -#else -uctolower(code) -unsigned long code; -#endif { int field; long l, r; @@ -482,12 +446,7 @@ unsigned long code; } unsigned long -#ifdef __STDC__ uctotitle(unsigned long code) -#else -uctotitle(code) -unsigned long code; -#endif { int field; long l, r; @@ -516,6 +475,196 @@ unsigned long code; return _uccase_lookup(code, l, r, field); } +/************************************************************************** + * + * Support for compositions. + * + **************************************************************************/ + +static unsigned long _uccomp_size; +static unsigned long *_uccomp_data; + +/* + * Return -1 on error, 0 if okay + */ +static int +_uccomp_load(char *paths, int reload) +{ + FILE *in; + unsigned long size, i; + _ucheader_t hdr; + + if (_uccomp_size > 0) { + if (!reload) + /* + * The compositions have already been loaded. + */ + return 0; + + free((char *) _uccomp_data); + _uccomp_size = 0; + } + + if ((in = _ucopenfile(paths, "comp.dat", "rb")) == 0) + return -1; + + /* + * Load the header. + */ + fread((char *) &hdr, sizeof(_ucheader_t), 1, in); + + if (hdr.bom == 0xfffe) { + hdr.cnt = endian_short(hdr.cnt); + hdr.size.bytes = endian_long(hdr.size.bytes); + } + + _uccomp_size = hdr.cnt; + _uccomp_data = (unsigned long *) malloc(hdr.size.bytes); + + /* + * Read the composition data in. + */ + size = hdr.size.bytes / sizeof(unsigned long); + fread((char *) _uccomp_data, sizeof(unsigned long), size, in); + + /* + * Do an endian swap if necessary. + */ + if (hdr.bom == 0xfffe) { + for (i = 0; i < size; i++) + _uccomp_data[i] = endian_long(_uccomp_data[i]); + } + + /* + * Assume that the data is ordered on count, so that all compositions + * of length 2 come first. Only handling length 2 for now. + */ + for (i = 1; i < size; i += 4) + if (_uccomp_data[i] != 2) + break; + _uccomp_size = i - 1; + + fclose(in); + return 0; +} + +static void +_uccomp_unload(void) +{ + if (_uccomp_size == 0) + return; + + free((char *) _uccomp_data); + _uccomp_size = 0; +} + +int +uccomp(unsigned long node1, unsigned long node2, unsigned long *comp) +{ + int l, r, m; + + l = 0; + r = _uccomp_size - 1; + + while (l <= r) { + m = ((r + l) >> 1); + m -= m & 3; + if (node1 > _uccomp_data[m+2]) + l = m + 4; + else if (node1 < _uccomp_data[m+2]) + r = m - 4; + else if (node2 > _uccomp_data[m+3]) + l = m + 4; + else if (node2 < _uccomp_data[m+3]) + r = m - 4; + else { + *comp = _uccomp_data[m]; + return 1; + } + } + return 0; +} + +int +uccomp_hangul(unsigned long *str, int len) +{ + const int SBase = 0xAC00, LBase = 0x1100, + VBase = 0x1161, TBase = 0x11A7, + LCount = 19, VCount = 21, TCount = 28, + NCount = VCount * TCount, /* 588 */ + SCount = LCount * NCount; /* 11172 */ + + int i, rlen; + unsigned long ch, last, lindex, sindex; + + last = str[0]; + rlen = 1; + for ( i = 1; i < len; i++ ) { + ch = str[i]; + + /* check if two current characters are L and V */ + lindex = last - LBase; + if (lindex < (unsigned long) LCount) { + unsigned long vindex = ch - VBase; + if (vindex < (unsigned long) VCount) { + /* make syllable of form LV */ + last = SBase + (lindex * VCount + vindex) * TCount; + str[rlen-1] = last; /* reset last */ + continue; + } + } + + /* check if two current characters are LV and T */ + sindex = last - SBase; + if (sindex < (unsigned long) SCount + && (sindex % TCount) == 0) + { + unsigned long tindex = ch - TBase; + if (tindex <= (unsigned long) TCount) { + /* make syllable of form LVT */ + last += tindex; + str[rlen-1] = last; /* reset last */ + continue; + } + } + + /* if neither case was true, just add the character */ + last = ch; + str[rlen] = ch; + rlen++; + } + return rlen; +} + +int +uccanoncomp(unsigned long *str, int len) +{ + int i, stpos, copos; + unsigned long cl, prevcl, st, ch, co; + + st = str[0]; + stpos = 0; + copos = 1; + prevcl = uccombining_class(st) == 0 ? 0 : 256; + + for (i = 1; i < len; i++) { + ch = str[i]; + cl = uccombining_class(ch); + if (uccomp(st, ch, &co) && (prevcl < cl || prevcl == 0)) + st = str[stpos] = co; + else { + if (cl == 0) { + stpos = copos; + st = ch; + } + prevcl = cl; + str[copos++] = ch; + } + } + + return uccomp_hangul(str, copos); +} + /************************************************************************** * * Support for decompositions. @@ -526,14 +675,15 @@ static unsigned long _ucdcmp_size; static unsigned long *_ucdcmp_nodes; static unsigned long *_ucdcmp_decomp; -static void -#ifdef __STDC__ +static unsigned long _uckdcmp_size; +static unsigned long *_uckdcmp_nodes; +static unsigned long *_uckdcmp_decomp; + +/* + * Return -1 on error, 0 if okay + */ +static int _ucdcmp_load(char *paths, int reload) -#else -_ucdcmp_load(paths, reload) -char *paths; -int reload; -#endif { FILE *in; unsigned long size, i; @@ -541,17 +691,17 @@ int reload; if (_ucdcmp_size > 0) { if (!reload) - /* - * The decompositions have already been loaded. - */ - return; + /* + * The decompositions have already been loaded. + */ + return 0; free((char *) _ucdcmp_nodes); _ucdcmp_size = 0; } if ((in = _ucopenfile(paths, "decomp.dat", "rb")) == 0) - return; + return -1; /* * Load the header. @@ -578,16 +728,69 @@ int reload; */ if (hdr.bom == 0xfffe) { for (i = 0; i < size; i++) - _ucdcmp_nodes[i] = endian_long(_ucdcmp_nodes[i]); - } + _ucdcmp_nodes[i] = endian_long(_ucdcmp_nodes[i]); + } + fclose(in); + return 0; +} + +/* + * Return -1 on error, 0 if okay + */ +static int +_uckdcmp_load(char *paths, int reload) +{ + FILE *in; + unsigned long size, i; + _ucheader_t hdr; + + if (_uckdcmp_size > 0) { + if (!reload) + /* + * The decompositions have already been loaded. + */ + return 0; + + free((char *) _uckdcmp_nodes); + _uckdcmp_size = 0; + } + + if ((in = _ucopenfile(paths, "kdecomp.dat", "rb")) == 0) + return -1; + + /* + * Load the header. + */ + fread((char *) &hdr, sizeof(_ucheader_t), 1, in); + + if (hdr.bom == 0xfffe) { + hdr.cnt = endian_short(hdr.cnt); + hdr.size.bytes = endian_long(hdr.size.bytes); + } + + _uckdcmp_size = hdr.cnt << 1; + _uckdcmp_nodes = (unsigned long *) malloc(hdr.size.bytes); + _uckdcmp_decomp = _uckdcmp_nodes + (_uckdcmp_size + 1); + + /* + * Read the decomposition data in. + */ + size = hdr.size.bytes / sizeof(unsigned long); + fread((char *) _uckdcmp_nodes, sizeof(unsigned long), size, in); + + /* + * Do an endian swap if necessary. + */ + if (hdr.bom == 0xfffe) { + for (i = 0; i < size; i++) + _uckdcmp_nodes[i] = endian_long(_uckdcmp_nodes[i]); + } + fclose(in); + return 0; } static void -#ifdef __STDC__ _ucdcmp_unload(void) -#else -_ucdcmp_unload() -#endif { if (_ucdcmp_size == 0) return; @@ -600,16 +803,29 @@ _ucdcmp_unload() _ucdcmp_size = 0; } +static void +_uckdcmp_unload(void) +{ + if (_uckdcmp_size == 0) + return; + + /* + * Only need to free the offsets because the memory is allocated as a + * single block. + */ + free((char *) _uckdcmp_nodes); + _uckdcmp_size = 0; +} + int -#ifdef __STDC__ ucdecomp(unsigned long code, unsigned long *num, unsigned long **decomp) -#else -ucdecomp(code, num, decomp) -unsigned long code, *num, **decomp; -#endif { long l, r, m; + if (code < _ucdcmp_nodes[0]) { + return 0; + } + l = 0; r = _ucdcmp_nodes[_ucdcmp_size] - 1; @@ -634,12 +850,39 @@ unsigned long code, *num, **decomp; } int -#ifdef __STDC__ +uckdecomp(unsigned long code, unsigned long *num, unsigned long **decomp) +{ + long l, r, m; + + if (code < _uckdcmp_nodes[0]) { + return 0; + } + + l = 0; + r = _uckdcmp_nodes[_uckdcmp_size] - 1; + + while (l <= r) { + /* + * Determine a "mid" point and adjust to make sure the mid point is at + * the beginning of a code+offset pair. + */ + m = (l + r) >> 1; + m -= (m & 1); + if (code > _uckdcmp_nodes[m]) + l = m + 2; + else if (code < _uckdcmp_nodes[m]) + r = m - 2; + else if (code == _uckdcmp_nodes[m]) { + *num = _uckdcmp_nodes[m + 3] - _uckdcmp_nodes[m + 1]; + *decomp = &_uckdcmp_decomp[_uckdcmp_nodes[m + 1]]; + return 1; + } + } + return 0; +} + +int ucdecomp_hangul(unsigned long code, unsigned long *num, unsigned long decomp[]) -#else -ucdecomp_hangul(code, num, decomp) -unsigned long code, *num, decomp[]; -#endif { if (!ucishangul(code)) return 0; @@ -653,6 +896,90 @@ unsigned long code, *num, decomp[]; return 1; } +/* mode == 0 for canonical, mode == 1 for compatibility */ +static int +uccanoncompatdecomp(const unsigned long *in, int inlen, + unsigned long **out, int *outlen, short mode) +{ + int l, size; + unsigned i, j, k; + unsigned long num, class, *decomp, hangdecomp[3]; + + size = inlen; + *out = (unsigned long *) malloc(size * sizeof(**out)); + if (*out == NULL) + return *outlen = -1; + + i = 0; + for (j = 0; j < (unsigned) inlen; j++) { + if (mode ? uckdecomp(in[j], &num, &decomp) : ucdecomp(in[j], &num, &decomp)) { + if ( size - i < num) { + size = inlen + i - j + num - 1; + *out = (unsigned long *) realloc(*out, size * sizeof(**out)); + if (*out == NULL) + return *outlen = -1; + } + for (k = 0; k < num; k++) { + class = uccombining_class(decomp[k]); + if (class == 0) { + (*out)[i] = decomp[k]; + } else { + for (l = i; l > 0; l--) + if (class >= uccombining_class((*out)[l-1])) + break; + AC_MEMCPY(*out + l + 1, *out + l, (i - l) * sizeof(**out)); + (*out)[l] = decomp[k]; + } + i++; + } + } else if (ucdecomp_hangul(in[j], &num, hangdecomp)) { + if (size - i < num) { + size = inlen + i - j + num - 1; + *out = (unsigned long *) realloc(*out, size * sizeof(**out)); + if (*out == NULL) + return *outlen = -1; + } + for (k = 0; k < num; k++) { + (*out)[i] = hangdecomp[k]; + i++; + } + } else { + if (size - i < 1) { + size = inlen + i - j; + *out = (unsigned long *) realloc(*out, size * sizeof(**out)); + if (*out == NULL) + return *outlen = -1; + } + class = uccombining_class(in[j]); + if (class == 0) { + (*out)[i] = in[j]; + } else { + for (l = i; l > 0; l--) + if (class >= uccombining_class((*out)[l-1])) + break; + AC_MEMCPY(*out + l + 1, *out + l, (i - l) * sizeof(**out)); + (*out)[l] = in[j]; + } + i++; + } + } + return *outlen = i; +} + +int +uccanondecomp(const unsigned long *in, int inlen, + unsigned long **out, int *outlen) +{ + return uccanoncompatdecomp(in, inlen, out, outlen, 0); +} + +int +uccompatdecomp(const unsigned long *in, int inlen, + unsigned long **out, int *outlen) +{ + return uccanoncompatdecomp(in, inlen, out, outlen, 1); +} + /************************************************************************** * * Support for combining classes. @@ -662,14 +989,11 @@ unsigned long code, *num, decomp[]; static unsigned long _uccmcl_size; static unsigned long *_uccmcl_nodes; -static void -#ifdef __STDC__ +/* + * Return -1 on error, 0 if okay + */ +static int _uccmcl_load(char *paths, int reload) -#else -_uccmcl_load(paths, reload) -char *paths; -int reload; -#endif { FILE *in; unsigned long i; @@ -677,17 +1001,17 @@ int reload; if (_uccmcl_size > 0) { if (!reload) - /* - * The combining classes have already been loaded. - */ - return; + /* + * The combining classes have already been loaded. + */ + return 0; free((char *) _uccmcl_nodes); _uccmcl_size = 0; } if ((in = _ucopenfile(paths, "cmbcl.dat", "rb")) == 0) - return; + return -1; /* * Load the header. @@ -712,16 +1036,14 @@ int reload; */ if (hdr.bom == 0xfffe) { for (i = 0; i < _uccmcl_size; i++) - _uccmcl_nodes[i] = endian_long(_uccmcl_nodes[i]); - } + _uccmcl_nodes[i] = endian_long(_uccmcl_nodes[i]); + } + fclose(in); + return 0; } static void -#ifdef __STDC__ _uccmcl_unload(void) -#else -_uccmcl_unload() -#endif { if (_uccmcl_size == 0) return; @@ -731,12 +1053,7 @@ _uccmcl_unload() } unsigned long -#ifdef __STDC__ uccombining_class(unsigned long code) -#else -uccombining_class(code) -unsigned long code; -#endif { long l, r, m; @@ -766,14 +1083,11 @@ static unsigned long *_ucnum_nodes; static unsigned long _ucnum_size; static short *_ucnum_vals; -static void -#ifdef __STDC__ +/* + * Return -1 on error, 0 if okay + */ +static int _ucnumb_load(char *paths, int reload) -#else -_ucnumb_load(paths, reload) -char *paths; -int reload; -#endif { FILE *in; unsigned long size, i; @@ -784,14 +1098,14 @@ int reload; /* * The numbers have already been loaded. */ - return; + return 0; free((char *) _ucnum_nodes); _ucnum_size = 0; } if ((in = _ucopenfile(paths, "num.dat", "rb")) == 0) - return; + return -1; /* * Load the header. @@ -828,15 +1142,13 @@ int reload; for (i = 0; i < size; i++) _ucnum_vals[i] = endian_short(_ucnum_vals[i]); - } + } + fclose(in); + return 0; } static void -#ifdef __STDC__ _ucnumb_unload(void) -#else -_ucnumb_unload() -#endif { if (_ucnum_size == 0) return; @@ -846,13 +1158,7 @@ _ucnumb_unload() } int -#ifdef __STDC__ ucnumber_lookup(unsigned long code, struct ucnumber *num) -#else -ucnumber_lookup(code, num) -unsigned long code; -struct ucnumber *num; -#endif { long l, r, m; short *vp; @@ -881,13 +1187,7 @@ struct ucnumber *num; } int -#ifdef __STDC__ ucdigit_lookup(unsigned long code, int *digit) -#else -ucdigit_lookup(code, digit) -unsigned long code; -int *digit; -#endif { long l, r, m; short *vp; @@ -918,12 +1218,7 @@ int *digit; } struct ucnumber -#ifdef __STDC__ ucgetnumber(unsigned long code) -#else -ucgetnumber(code) -unsigned long code; -#endif { struct ucnumber num; @@ -940,12 +1235,7 @@ unsigned long code; } int -#ifdef __STDC__ ucgetdigit(unsigned long code) -#else -ucgetdigit(code) -unsigned long code; -#endif { int dig; @@ -967,34 +1257,34 @@ unsigned long code; * **************************************************************************/ -void -#ifdef __STDC__ +/* + * Return 0 if okay, negative on error + */ +int ucdata_load(char *paths, int masks) -#else -ucdata_load(paths, masks) -char *paths; -int masks; -#endif { + int error = 0; + if (masks & UCDATA_CTYPE) - _ucprop_load(paths, 0); + error |= _ucprop_load(paths, 0) < 0 ? UCDATA_CTYPE : 0; if (masks & UCDATA_CASE) - _uccase_load(paths, 0); + error |= _uccase_load(paths, 0) < 0 ? UCDATA_CASE : 0; if (masks & UCDATA_DECOMP) - _ucdcmp_load(paths, 0); + error |= _ucdcmp_load(paths, 0) < 0 ? UCDATA_DECOMP : 0; if (masks & UCDATA_CMBCL) - _uccmcl_load(paths, 0); + error |= _uccmcl_load(paths, 0) < 0 ? UCDATA_CMBCL : 0; if (masks & UCDATA_NUM) - _ucnumb_load(paths, 0); + error |= _ucnumb_load(paths, 0) < 0 ? UCDATA_NUM : 0; + if (masks & UCDATA_COMP) + error |= _uccomp_load(paths, 0) < 0 ? UCDATA_COMP : 0; + if (masks & UCDATA_KDECOMP) + error |= _uckdcmp_load(paths, 0) < 0 ? UCDATA_KDECOMP : 0; + + return -error; } void -#ifdef __STDC__ ucdata_unload(int masks) -#else -ucdata_unload(masks) -int masks; -#endif { if (masks & UCDATA_CTYPE) _ucprop_unload(); @@ -1006,37 +1296,42 @@ int masks; _uccmcl_unload(); if (masks & UCDATA_NUM) _ucnumb_unload(); + if (masks & UCDATA_COMP) + _uccomp_unload(); + if (masks & UCDATA_KDECOMP) + _uckdcmp_unload(); } -void -#ifdef __STDC__ +/* + * Return 0 if okay, negative on error + */ +int ucdata_reload(char *paths, int masks) -#else -ucdata_reload(paths, masks) -char *paths; -int masks; -#endif { + int error = 0; + if (masks & UCDATA_CTYPE) - _ucprop_load(paths, 1); + error |= _ucprop_load(paths, 1) < 0 ? UCDATA_CTYPE : 0; if (masks & UCDATA_CASE) - _uccase_load(paths, 1); + error |= _uccase_load(paths, 1) < 0 ? UCDATA_CASE : 0; if (masks & UCDATA_DECOMP) - _ucdcmp_load(paths, 1); + error |= _ucdcmp_load(paths, 1) < 0 ? UCDATA_DECOMP : 0; if (masks & UCDATA_CMBCL) - _uccmcl_load(paths, 1); + error |= _uccmcl_load(paths, 1) < 0 ? UCDATA_CMBCL : 0; if (masks & UCDATA_NUM) - _ucnumb_load(paths, 1); + error |= _ucnumb_load(paths, 1) < 0 ? UCDATA_NUM : 0; + if (masks & UCDATA_COMP) + error |= _uccomp_load(paths, 1) < 0 ? UCDATA_COMP : 0; + if (masks & UCDATA_KDECOMP) + error |= _uckdcmp_load(paths, 1) < 0 ? UCDATA_KDECOMP : 0; + + return -error; } #ifdef TEST void -#ifdef __STDC__ main(void) -#else -main() -#endif { int dig; unsigned long i, lo, *dec;