gettext_util.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "synonyms.h"
#include "mtlib.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <thread.h>
#include <synch.h>
#include <limits.h>
#include <unistd.h>
#include <langinfo.h>
#include "libc.h"
#include "_loc_path.h"
#include "msgfmt.h"
#include "gettext.h"
#ifdef GETTEXT_DEBUG
#include "plural_parser.h"
#include <stdarg.h>
#endif
static const char *category_name[] = {
"LC_CTYPE",
"LC_NUMERIC",
"LC_TIME",
"LC_COLLATE",
"LC_MONETARY",
"LC_MESSAGES"
};
static const int category_name_len[] = {
8,
10,
7,
10,
11,
11
};
static int
{
#ifdef GETTEXT_DEBUG
(void) printf("*************** setmo(0x%p, %d)\n",
#endif
switch (type) {
case T_ILL_MO:
/* invalid MO */
#ifdef GETTEXT_DEBUG
(void) printf("*************** exiting setmo\n");
#endif
return (0);
case T_SUN_MO:
{
struct msg_info *sun_header;
Msg_s_node *p;
if (!p) {
return (-1);
}
/* LINTED */
p->msg_file_info = sun_header;
/* LINTED */
#ifdef GETTEXT_DEBUG
(void) printf("*************** exiting setmo\n");
#endif
return (0);
}
/* NOTREACHED */
case T_GNU_MO:
case T_GNU_SWAPPED_MO:
{
struct gnu_msg_info *gnu_header;
Msg_g_node *p;
if (!p) {
return (-1);
}
/* LINTED */
p->msg_file_info = gnu_header;
if (type == T_GNU_SWAPPED_MO) {
/*
* This MO file has been created on
* the reversed endian system
*/
}
/* LINTED */
p->hash_table = (unsigned int *)(((char *)addr) +
#ifdef GETTEXT_DEBUG
(void) printf("*************** exiting setmo\n");
#endif
return (0);
}
/* NOTREACHED */
}
/* NOTREACHED */
return (0); /* keep gcc happy */
}
/*
* setmsg
*
* INPUT
* mnp - message node
* addr - address to the mmapped file
* size - size of the file
*
* RETURN
* 0 - succeeded
* -1 - failed
*/
int
{
struct msg_info *sun_header;
struct gnu_msg_info *gnu_header;
unsigned int first_4bytes;
int struct_size, struct_size_old;
int msg_struct_size;
/* invalid mo file */
}
/* LINTED */
first_4bytes = *((unsigned int *)addr);
if (first_4bytes <= INT_MAX) {
/* candidate for sun mo */
/* LINTED */
((msg_struct_size == struct_size_old) ||
(msg_struct_size == struct_size))) {
/* valid sun mo file */
}
/* invalid mo file */
}
/* checks the GNU MAGIC number */
if (size < sizeof (struct gnu_msg_info)) {
/* invalid mo file */
}
/* LINTED */
/* GNU mo file */
/* endian-swapped GNU mo file */
}
/* invalid mo file */
}
/*
* mk_msgfile
*
* INPUT
* mp - uses the following members:
* msgfile - buffer to store the pathname to the message file
* binding - directory pathname bound to specified domain
* cblen - length of binding
* locale - locale name
* domain - domain name
* category - category
* locale_len - length of locale name
* domain_len - length of domain name
*
* OUTPUT
* mp->msgfile - pathname to the message file is stored
* mp->msgfile_len - length of mp->msgfile without null termination
*
* RETURN
* mp->msgfile is returned
*/
char *
{
char *p, *q;
const char *catstr;
#ifdef GETTEXT_DEBUG
(void) printf("*************** mk_msgfile(0x%p)\n",
(void *)mp);
#endif
while (*p = *q++)
p++;
if (*(p - 1) != '/') {
/*
* if the last character of binding
* isn't a '/', adding '/'.
*/
/* MAXPATHLEN includes a null termination */
return (NULL);
}
*p++ = '/';
cblen++;
}
/*
* totallen is the length of the msgfile
* pathname excluding a null termination.
*/
if (totallen >= MAXPATHLEN)
return (NULL);
while (*p++ = *q++)
;
*(p - 1) = '/';
while (*p++ = *catstr++)
;
*(p - 1) = '/';
while (*p++ = *q++)
;
*(p - 1) = '.';
*p = 'm';
*(p + 1) = 'o';
*(p + 2) = '\0';
#ifdef GETTEXT_DEBUG
(void) printf("*************** Exiting mk_msgfile\n");
#endif
}
/*
* check_cache
*
* INPUT
* cp - may use the following members:
* node_hash - pointer to the Cache_node object having this locale
*
* mp - may use the following members:
* msgfile - pathname to the message catalog file
* hash_locale - hash id of this locale
*
* OUTPUT
* cp - may update the following members:
* mnp - pointer to a Msg_node object
* cnp - pointer to a Cache_node object
* node_hash - pointer to the Cache_node object having this locale
* cacheline - flag to show if the Cache_node for this locale exists
*
* RETURN
* 1 - Entry for this message catalog exists in the cache
* 0 - Entry for this message catalog doesn't exist in the cache
*/
int
{
#ifdef GETTEXT_DEBUG
{
int level = 0;
(void) printf("*************** check_cache(0x%p, 0x%p)\n",
}
#endif
if (cur_msg &&
/*
* msgfile is the same as the previous message file
*/
#ifdef GETTEXT_DEBUG
(void) printf("************* exiting check_cache\n");
(void) printf("cache found\n");
#endif
return (1);
}
/*
* already cache_node having the same
* hash id found
*/
#ifdef GETTEXT_DEBUG
(void) printf("************* exiting check_cache\n");
(void) printf("cache found\n");
#endif
return (1);
}
}
#ifdef GETTEXT_DEBUG
(void) printf("************* exiting check_cache\n");
(void) printf("cache not found\n");
#endif
return (0);
}
/* search the cache list */
/*
* msgfile found in the cache
*/
#ifdef GETTEXT_DEBUG
(void) printf("************* exiting check_cache\n");
(void) printf("cache found\n");
#endif
return (1);
}
}
#ifdef GETTEXT_DEBUG
(void) printf("************* exiting check_cache\n");
(void) printf("cache not found\n");
#endif
return (0);
} else {
}
}
#ifdef GETTEXT_DEBUG
(void) printf("************* exiting check_cache\n");
(void) printf("cache not found\n");
#endif
return (0);
}
char *
get_codeset(const char *domain)
{
char *codeset;
#ifdef GETTEXT_DEBUG
(void) printf("*************** get_codeset(\"%s\")\n",
#endif
if (!codeset) {
/* no codeset is bound to this domain */
}
#ifdef GETTEXT_DEBUG
(void) printf("*************** existing get_codeset(\"%s\")\n",
#endif
return (codeset);
}
void
{
#ifdef GETTEXT_DEBUG
(void) printf("*************** connect_entry(0x%p)\n",
(void *)cp);
#endif
else
} else {
else
}
}
int
{
#ifdef GETTEXT_DEBUG
(void) printf("*************** connect_invalid_entry(0x%p, 0x%p)\n",
#endif
return (-1);
}
return (-1);
}
}
return (0);
}
Msg_node *
{
char *s;
#ifdef GETTEXT_DEBUG
#endif
if (!mnp) {
return (NULL);
}
if (!s) {
return (NULL);
}
return (mnp);
}
{
#ifdef GETTEXT_DEBUG
(void) printf("*************** create_cnp(0x%p, 0x%p)\n",
#endif
if (!cnp) {
return (NULL);
}
return (cnp);
}
void
{
#ifdef GETTEXT_DEBUG
(void) printf("*************** free_mnp_mp(0x%p, 0x%p)\n",
#endif
if (mnp) {
case T_SUN_MO:
break;
case T_GNU_MO:
break;
}
}
}
}
/*
* get_hashid
*
* Calculates the hash value from the specified string.
* Actual hashid will be mod(hash value, PRIME_NUMBER).
*
* hashpjw
* Ref: Compilers - Principles, Techniques, and Tools
* Aho, Sethi, and Ullman
*/
unsigned int
{
const char *p;
unsigned int h = 0, g;
for (p = str; *p; p++) {
h = (h << 4) + *p;
g = h & 0xf0000000;
if (g) {
h = h ^ (g >> 24);
h = h ^ g;
}
}
if (len)
return (h);
}
unsigned int
doswap32(unsigned int n)
{
unsigned int r;
r = (n << 24) | ((n & 0xff00) << 8) |
((n >> 8) & 0xff00) | (n >> 24);
return (r);
}
#ifdef GETTEXT_DEBUG
void
{
while (level-- >= 0) {
}
}
void
printlist(void)
{
struct domain_binding *ppp;
(void) printf("=== Printing default list and regural list\n");
(void) printf(" Default domain=<%s>, binding=<%s>\n",
while (ppp) {
(void) printf(
" domain=<%s>, binding=<%s>, codeset=<%s>\n",
}
}
void
{
}
void
{
(void *)smnp->msg_file_info);
}
void
{
(void *)gmnp->msg_file_info);
(void *)gmnp->hash_table);
gmnp->header_flag);
(void *)gmnp->conv_msgstr);
}
void
{
static const char *op_name[] = {
"NULL", "INIT", "EXP",
"NUM", "VAR", "?", ":", "||",
"&&", "==", "!=", ">", "<",
">=", "<=", "+", "-", "*", "/",
"%", "!", "(", ")", "ERR"
};
case 0:
case T_NUM:
break;
case T_VAR:
break;
}
break;
case 1:
break;
case 2:
break;
case 3:
break;
}
}
void
{
"UNKNOWN TYPE");
}
void
{
}
void
{
}
#endif