diff options
Diffstat (limited to 'usr/src/lib/libast/common/port/mc.c')
-rw-r--r-- | usr/src/lib/libast/common/port/mc.c | 677 |
1 files changed, 0 insertions, 677 deletions
diff --git a/usr/src/lib/libast/common/port/mc.c b/usr/src/lib/libast/common/port/mc.c deleted file mode 100644 index 5c26513f2f..0000000000 --- a/usr/src/lib/libast/common/port/mc.c +++ /dev/null @@ -1,677 +0,0 @@ -/*********************************************************************** -* * -* This software is part of the ast package * -* Copyright (c) 1985-2010 AT&T Intellectual Property * -* and is licensed under the * -* Common Public License, Version 1.0 * -* by AT&T Intellectual Property * -* * -* A copy of the License is available at * -* http://www.opensource.org/licenses/cpl1.0.txt * -* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * -* * -* Information and Software Systems Research * -* AT&T Research * -* Florham Park NJ * -* * -* Glenn Fowler <gsf@research.att.com> * -* David Korn <dgk@research.att.com> * -* Phong Vo <kpv@research.att.com> * -* * -***********************************************************************/ -#pragma prototyped - -/* - * Glenn Fowler - * AT&T Research - * - * machine independent binary message catalog implementation - */ - -#include "sfhdr.h" -#include "lclib.h" - -#include <iconv.h> - -#define _MC_PRIVATE_ \ - size_t nstrs; \ - size_t nmsgs; \ - iconv_t cvt; \ - Sfio_t* tmp; \ - Vmalloc_t* vm; - -#include <vmalloc.h> -#include <error.h> -#include <mc.h> -#include <nl_types.h> - -/* - * find the binary message catalog path for <locale,catalog> - * result placed in path of size PATH_MAX - * pointer to path returned - * catalog==0 tests for category directory or file - * nls!=0 enables NLSPATH+LANG hack (not implemented yet) - */ - -char* -mcfind(char* path, const char* locale, const char* catalog, int category, int nls) -{ - register int c; - register char* s; - register char* e; - register char* p; - register const char* v; - int i; - int first; - int next; - int last; - int oerrno; - Lc_t* lc; - char file[PATH_MAX]; - char* paths[5]; - - static char lc_messages[] = "LC_MESSAGES"; - - if ((category = lcindex(category, 1)) < 0) - return 0; - if (!(lc = locale ? lcmake(locale) : locales[category])) - return 0; - oerrno = errno; - if (catalog && *catalog == '/') - { - i = eaccess(catalog, R_OK); - errno = oerrno; - if (i) - return 0; - strncpy(path, catalog, PATH_MAX-1); - return path; - } - i = 0; -#if !_lib_catopen - if ((p = getenv("NLSPATH")) && *p) - paths[i++] = p; -#endif - paths[i++] = "share/lib/locale/%l/%C/%N"; - paths[i++] = "share/locale/%l/%C/%N"; - paths[i++] = "lib/locale/%l/%C/%N"; - paths[i] = 0; - next = 1; - for (i = 0; p = paths[i]; i += next) - { - first = 1; - last = 0; - e = &file[elementsof(file) - 1]; - while (*p) - { - s = file; - for (;;) - { - switch (c = *p++) - { - case 0: - p--; - break; - case ':': - break; - case '%': - if (s < e) - { - switch (c = *p++) - { - case 0: - p--; - continue; - case 'N': - v = catalog; - break; - case 'L': - if (first) - { - first = 0; - if (next) - { - v = lc->code; - if (lc->code != lc->language->code) - next = 0; - } - else - { - next = 1; - v = lc->language->code; - } - } - break; - case 'l': - v = lc->language->code; - break; - case 't': - v = lc->territory->code; - break; - case 'c': - v = lc->charset->code; - break; - case 'C': - case_C: - if (!catalog) - last = 1; - v = lc_categories[category].name; - break; - default: - *s++ = c; - continue; - } - if (v) - while (*v && s < e) - *s++ = *v++; - } - continue; - case '/': - if (last) - break; - if (category != AST_LC_MESSAGES && strneq(p, lc_messages, sizeof(lc_messages) - 1) && p[sizeof(lc_messages)-1] == '/') - { - p += sizeof(lc_messages) - 1; - goto case_C; - } - /*FALLTHROUGH*/ - default: - if (s < e) - *s++ = c; - continue; - } - break; - } - if (s > file) - *s = 0; - else if (!catalog) - continue; - else - strncpy(file, catalog, elementsof(file)); - if (ast.locale.set & AST_LC_find) - sfprintf(sfstderr, "locale find %s\n", file); - if (s = pathpath(path, file, "", (!catalog && category == AST_LC_MESSAGES) ? PATH_READ : (PATH_REGULAR|PATH_READ|PATH_ABSOLUTE))) - { - if (ast.locale.set & (AST_LC_find|AST_LC_setlocale)) - sfprintf(sfstderr, "locale path %s\n", s); - errno = oerrno; - return s; - } - } - } - errno = oerrno; - return 0; -} - -/* - * allocate and read the binary message catalog ip - * if ip==0 then space is allocated for mcput() - * 0 returned on any error - */ - -Mc_t* -mcopen(register Sfio_t* ip) -{ - register Mc_t* mc; - register char** mp; - register char* sp; - Vmalloc_t* vm; - char* rp; - int i; - int j; - int oerrno; - size_t n; - char buf[MC_MAGIC_SIZE]; - - oerrno = errno; - if (ip) - { - /* - * check the magic - */ - - if (sfread(ip, buf, MC_MAGIC_SIZE) != MC_MAGIC_SIZE) - { - errno = oerrno; - return 0; - } - if (memcmp(buf, MC_MAGIC, MC_MAGIC_SIZE)) - return 0; - } - - /* - * allocate the region - */ - - if (!(vm = vmopen(Vmdcheap, Vmbest, 0)) || !(mc = vmnewof(vm, 0, Mc_t, 1, 0))) - { - errno = oerrno; - return 0; - } - mc->vm = vm; - mc->cvt = (iconv_t)(-1); - if (ip) - { - /* - * read the translation record - */ - - if (!(sp = sfgetr(ip, 0, 0)) || !(mc->translation = vmstrdup(vm, sp))) - goto bad; - - /* - * read the optional header records - */ - - do - { - if (!(sp = sfgetr(ip, 0, 0))) - goto bad; - } while (*sp); - - /* - * get the component dimensions - */ - - mc->nstrs = sfgetu(ip); - mc->nmsgs = sfgetu(ip); - mc->num = sfgetu(ip); - if (sfeof(ip)) - goto bad; - } - else if (!(mc->translation = vmnewof(vm, 0, char, 1, 0))) - goto bad; - - /* - * allocate the remaining space - */ - - if (!(mc->set = vmnewof(vm, 0, Mcset_t, mc->num + 1, 0))) - goto bad; - if (!ip) - return mc; - if (!(mp = vmnewof(vm, 0, char*, mc->nmsgs + mc->num + 1, 0))) - goto bad; - if (!(rp = sp = vmalloc(vm, mc->nstrs + 1))) - goto bad; - - /* - * get the set dimensions and initialize the msg pointers - */ - - while (i = sfgetu(ip)) - { - if (i > mc->num) - goto bad; - n = sfgetu(ip); - mc->set[i].num = n; - mc->set[i].msg = mp; - mp += n + 1; - } - - /* - * read the msg sizes and set up the msg pointers - */ - - for (i = 1; i <= mc->num; i++) - for (j = 1; j <= mc->set[i].num; j++) - if (n = sfgetu(ip)) - { - mc->set[i].msg[j] = sp; - sp += n; - } - - /* - * read the string table - */ - - if (sfread(ip, rp, mc->nstrs) != mc->nstrs || sfgetc(ip) != EOF) - goto bad; - if (!(mc->tmp = sfstropen())) - goto bad; - mc->cvt = iconv_open("", "utf"); - errno = oerrno; - return mc; - bad: - vmclose(vm); - errno = oerrno; - return 0; -} - -/* - * return the <set,num> message in mc - * msg returned on error - * utf message text converted to ucs - */ - -char* -mcget(register Mc_t* mc, int set, int num, const char* msg) -{ - char* s; - size_t n; - int p; - - if (!mc || set < 0 || set > mc->num || num < 1 || num > mc->set[set].num || !(s = mc->set[set].msg[num])) - return (char*)msg; - if (mc->cvt == (iconv_t)(-1)) - return s; - if ((p = sfstrtell(mc->tmp)) > sfstrsize(mc->tmp) / 2) - { - p = 0; - sfstrseek(mc->tmp, p, SEEK_SET); - } - n = strlen(s) + 1; - iconv_write(mc->cvt, mc->tmp, &s, &n, NiL); - return sfstrbase(mc->tmp) + p; -} - -/* - * set message <set,num> to msg - * msg==0 deletes the message - * the message and set counts are adjusted - * 0 returned on success, -1 otherwise - */ - -int -mcput(register Mc_t* mc, int set, int num, const char* msg) -{ - register int i; - register char* s; - register Mcset_t* sp; - register char** mp; - - /* - * validate the arguments - */ - - if (!mc || set > MC_SET_MAX || num > MC_NUM_MAX) - return -1; - - /* - * deletions don't kick in allocations (duh) - */ - - if (!msg) - { - if (set <= mc->num && num <= mc->set[set].num && (s = mc->set[set].msg[num])) - { - /* - * decrease the string table size - */ - - mc->set[set].msg[num] = 0; - mc->nstrs -= strlen(s) + 1; - if (mc->set[set].num == num) - { - /* - * decrease the max msg num - */ - - mp = mc->set[set].msg + num; - while (num && !mp[--num]); - mc->nmsgs -= mc->set[set].num - num; - if (!(mc->set[set].num = num) && mc->num == set) - { - /* - * decrease the max set num - */ - - while (num && !mc->set[--num].num); - mc->num = num; - } - } - } - return 0; - } - - /* - * keep track of the highest set and allocate if necessary - */ - - if (set > mc->num) - { - if (set > mc->gen) - { - i = MC_SET_MAX; - if (!(sp = vmnewof(mc->vm, 0, Mcset_t, i + 1, 0))) - return -1; - mc->gen = i; - for (i = 1; i <= mc->num; i++) - sp[i] = mc->set[i]; - mc->set = sp; - } - mc->num = set; - } - sp = mc->set + set; - - /* - * keep track of the highest msg and allocate if necessary - */ - - if (num > sp->num) - { - if (num > sp->gen) - { - if (!mc->gen) - { - i = (MC_NUM_MAX + 1) / 32; - if (i <= num) - i = 2 * num; - if (i > MC_NUM_MAX) - i = MC_NUM_MAX; - if (!(mp = vmnewof(mc->vm, 0, char*, i + 1, 0))) - return -1; - mc->gen = i; - sp->msg = mp; - for (i = 1; i <= sp->num; i++) - mp[i] = sp->msg[i]; - } - else - { - i = 2 * mc->gen; - if (i > MC_NUM_MAX) - i = MC_NUM_MAX; - if (!(mp = vmnewof(mc->vm, sp->msg, char*, i + 1, 0))) - return -1; - sp->gen = i; - sp->msg = mp; - } - } - mc->nmsgs += num - sp->num; - sp->num = num; - } - - /* - * decrease the string table size - */ - - if (s = sp->msg[num]) - { - /* - * no-op if no change - */ - - if (streq(s, msg)) - return 0; - mc->nstrs -= strlen(s) + 1; - } - - /* - * allocate, add and adjust the string table size - */ - - if (!(s = vmstrdup(mc->vm, msg))) - return -1; - sp->msg[num] = s; - mc->nstrs += strlen(s) + 1; - return 0; -} - -/* - * dump message catalog mc to op - * 0 returned on success, -1 otherwise - */ - -int -mcdump(register Mc_t* mc, register Sfio_t* op) -{ - register int i; - register int j; - register int n; - register char* s; - register Mcset_t* sp; - - /* - * write the magic - */ - - if (sfwrite(op, MC_MAGIC, MC_MAGIC_SIZE) != MC_MAGIC_SIZE) - return -1; - - /* - * write the translation record - */ - - sfputr(op, mc->translation, 0); - - /* optional header records here */ - - /* - * end of optional header records - */ - - sfputu(op, 0); - - /* - * write the global dimensions - */ - - sfputu(op, mc->nstrs); - sfputu(op, mc->nmsgs); - sfputu(op, mc->num); - - /* - * write the set dimensions - */ - - for (i = 1; i <= mc->num; i++) - if (mc->set[i].num) - { - sfputu(op, i); - sfputu(op, mc->set[i].num); - } - sfputu(op, 0); - - /* - * write the message sizes - */ - - for (i = 1; i <= mc->num; i++) - if (mc->set[i].num) - { - sp = mc->set + i; - for (j = 1; j <= sp->num; j++) - { - n = (s = sp->msg[j]) ? (strlen(s) + 1) : 0; - sfputu(op, n); - } - } - - /* - * write the string table - */ - - for (i = 1; i <= mc->num; i++) - if (mc->set[i].num) - { - sp = mc->set + i; - for (j = 1; j <= sp->num; j++) - if (s = sp->msg[j]) - sfputr(op, s, 0); - } - - /* - * sync and return - */ - - return sfsync(op); -} - -/* - * parse <set,msg> number from s - * e!=0 is set to the next char after the parse - * set!=0 is set to message set number - * msg!=0 is set to message number - * the message set number is returned - * - * the base 36 hash gives reasonable values for these: - * - * "ast" : ((((36#a^36#s^36#t)-9)&63)+1) = 3 - * "gnu" : ((((36#g^36#n^36#u)-9)&63)+1) = 17 - * "sgi" : ((((36#s^36#g^36#i)-9)&63)+1) = 22 - * "sun" : ((((36#s^36#u^36#n)-9)&63)+1) = 13 - */ - -int -mcindex(register const char* s, char** e, int* set, int* msg) -{ - register int c; - register int m; - register int n; - register int r; - register unsigned char* cv; - char* t; - - m = 0; - n = strtol(s, &t, 0); - if (t == (char*)s) - { - SFCVINIT(); - cv = _Sfcv36; - for (n = m = 0; (c = cv[*s]) < 36; s++) - { - m++; - n ^= c; - } - m = (m <= 3) ? 63 : ((1 << (m + 3)) - 1); - n = ((n - 9) & m) + 1; - } - else - s = (const char*)t; - r = n; - if (*s) - m = strtol(s + 1, e, 0); - else - { - if (e) - *e = (char*)s; - if (m) - m = 0; - else - { - m = n; - n = 1; - } - } - if (set) - *set = n; - if (msg) - *msg = m; - return r; -} - -/* - * close the message catalog mc - */ - -int -mcclose(register Mc_t* mc) -{ - if (!mc) - return -1; - if (mc->tmp) - sfclose(mc->tmp); - if (mc->cvt != (iconv_t)(-1)) - iconv_close(mc->cvt); - vmclose(mc->vm); - return 0; -} |