summaryrefslogtreecommitdiff
path: root/usr/src/lib/libast/common/port/mc.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libast/common/port/mc.c')
-rw-r--r--usr/src/lib/libast/common/port/mc.c677
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;
-}