summaryrefslogtreecommitdiffstats
path: root/lib/libc/locale/ldpart.c
diff options
context:
space:
mode:
authorphantom <phantom@FreeBSD.org>2001-02-08 16:58:53 +0000
committerphantom <phantom@FreeBSD.org>2001-02-08 16:58:53 +0000
commite396ac20a49e0d26712570446f953f9d9bf9d89e (patch)
tree1155a486bc97ddafe35e68fb6b83097441faf7a8 /lib/libc/locale/ldpart.c
parentda5c9d8c01dd425a37752e03cd84e0e8bb25f2a0 (diff)
downloadFreeBSD-src-e396ac20a49e0d26712570446f953f9d9bf9d89e.zip
FreeBSD-src-e396ac20a49e0d26712570446f953f9d9bf9d89e.tar.gz
Make FreeBSD locale support complete: add support for rest locale categories
LC_MONETARY, LC_NUMERIC and LC_MESSAGES. Remove stub functions since they don't need anymore. Reviewed by: silence on -i18n
Diffstat (limited to 'lib/libc/locale/ldpart.c')
-rw-r--r--lib/libc/locale/ldpart.c165
1 files changed, 165 insertions, 0 deletions
diff --git a/lib/libc/locale/ldpart.c b/lib/libc/locale/ldpart.c
new file mode 100644
index 0000000..7675a0c
--- /dev/null
+++ b/lib/libc/locale/ldpart.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2000, 2001 Alexey Zelkin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/syslimits.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include "setlocale.h"
+#include "ldpart.h"
+
+static int split_lines(char *, const char *);
+static void set_from_buf(const char *, int, const char **);
+
+int
+__part_load_locale(const char *name,
+ int* using_locale,
+ char *locale_buf,
+ const char *category_name,
+ int locale_buf_size,
+ const char **dst_localebuf) {
+
+ static char locale_buf_C[] = "C";
+ static int num_lines;
+
+ int fd;
+ char * lbuf;
+ char * p;
+ const char * plim;
+ char filename[PATH_MAX];
+ struct stat st;
+ size_t namesize;
+ size_t bufsize;
+ int save_using_locale;
+
+ save_using_locale = *using_locale;
+ *using_locale = 0;
+
+ if (name == NULL)
+ goto no_locale;
+
+ if (!strcmp(name, "C") || !strcmp(name, "POSIX"))
+ return 0;
+
+ /*
+ ** If the locale name is the same as our cache, use the cache.
+ */
+ lbuf = locale_buf;
+ if (lbuf != NULL && strcmp(name, lbuf) == 0) {
+ set_from_buf(lbuf, num_lines, dst_localebuf);
+ *using_locale = 1;
+ return 0;
+ }
+ /*
+ ** Slurp the locale file into the cache.
+ */
+ namesize = strlen(name) + 1;
+
+ if (!_PathLocale)
+ goto no_locale;
+ /* Range checking not needed, 'name' size is limited */
+ strcpy(filename, _PathLocale);
+ strcat(filename, "/");
+ strcat(filename, name);
+ strcat(filename, "/");
+ strcat(filename, category_name);
+ fd = _open(filename, O_RDONLY);
+ if (fd < 0)
+ goto no_locale;
+ if (fstat(fd, &st) != 0)
+ goto bad_locale;
+ if (st.st_size <= 0)
+ goto bad_locale;
+ bufsize = namesize + st.st_size;
+ locale_buf = NULL;
+ lbuf = (lbuf == NULL || lbuf == locale_buf_C) ?
+ malloc(bufsize) : reallocf(lbuf, bufsize);
+ if (lbuf == NULL)
+ goto bad_locale;
+ (void) strcpy(lbuf, name);
+ p = lbuf + namesize;
+ plim = p + st.st_size;
+ if (_read(fd, p, (size_t) st.st_size) != st.st_size)
+ goto bad_lbuf;
+ if (_close(fd) != 0)
+ goto bad_lbuf;
+ /*
+ ** Parse the locale file into localebuf.
+ */
+ if (plim[-1] != '\n')
+ goto bad_lbuf;
+ num_lines = split_lines(p, plim);
+ if (num_lines >= locale_buf_size)
+ num_lines = locale_buf_size;
+ else
+ goto reset_locale;
+ set_from_buf(lbuf, num_lines, dst_localebuf);
+ /*
+ ** Record the successful parse in the cache.
+ */
+ locale_buf = lbuf;
+
+ *using_locale = 1;
+ return 0;
+
+reset_locale:
+ locale_buf = locale_buf_C;
+ save_using_locale = 0;
+bad_lbuf:
+ free(lbuf);
+bad_locale:
+ (void)_close(fd);
+no_locale:
+ *using_locale = save_using_locale;
+ return -1;
+}
+
+static int
+split_lines(char *p, const char *plim)
+{
+ int i;
+
+ for (i = 0; p < plim; i++) {
+ p = strchr(p, '\n');
+ *p++ = '\0';
+ }
+ return i;
+}
+
+static void
+set_from_buf(const char *p, int num_lines, const char **dst_localebuf)
+{
+ const char **ap;
+ int i;
+
+ for (ap = dst_localebuf, i = 0; i < num_lines; ++ap, ++i)
+ *ap = p += strlen(p) + 1;
+}
+
OpenPOWER on IntegriCloud