home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek Gadgets 1
/
ADE-1.bin
/
ade-dist
/
tar-1.11.8-src.tgz
/
tar.out
/
fsf
/
tar
/
intl
/
finddomain.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-28
|
6KB
|
238 lines
/* finddomain.c -- handle list of needed message catalogs
Copyright (C) 1995 Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gettext.h"
#include "gettextP.h"
#include "libgettext.h"
/* @@ end of prolog @@ */
/* Contains the default location of the message catalogs. */
const char _nl_default_dirname[] = DEF_MSG_DOM_DIR;
/* List with bindings of specific domains created by bindtextdomain()
calls. */
struct binding *_nl_domain_bindings;
/* List of already loaded domains. */
extern struct loaded_domain *_nl_loaded_domains;
/* Prototypes for library functions. */
char *xgetcwd ();
void *xmalloc ();
/* Prototypes for local functions. */
static const char *category_to_name __P((int category));
#if !defined HAVE_SETLOCALE || !defined HAVE_LC_MESSAGES
static const char *guess_category_value __P((int category,
const char *categoryname));
#endif
/* Return a data structure describing the message catalog described by
the DOMAINNAME and CATEGORY parameters with respect to the currently
established bindings. */
struct loaded_domain *
_nl_find_domain (domainname, category)
const char *domainname;
int category;
{
const char *categoryname;
const char *categoryvalue;
struct binding *binding;
char *dirname;
char *filename;
size_t filename_len;
struct loaded_domain *retval;
/* Now determine the symbolic name of CATEGORY and its value. */
categoryname = category_to_name (category);
#ifdef HAVE_SETLOCALE
# ifndef HAVE_LC_MESSAGES
if (category == LC_MESSAGES)
categoryvalue = guess_category_value (category, categoryname);
else
# endif
categoryvalue = setlocale (category, NULL);
#else
categoryvalue = guess_category_value (category, categoryname);
#endif
/* If the current locale value is C (or POSIX) we don't load a domain.
The causes the calling function to return the MSGID. */
if (strcmp (categoryvalue, "C") == 0 || strcmp (categoryvalue, "POSIX") == 0)
return NULL;
/* First find matching binding. */
for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
{
int compare = strcmp (domainname, binding->domainname);
if (compare == 0)
/* We found it! */
break;
if (compare < 0)
{
/* It is not in the list. */
binding = NULL;
break;
}
}
if (binding == NULL)
dirname = (char *) _nl_default_dirname;
else if (binding->dirname[0] == '/')
dirname = binding->dirname;
else
{
/* We have a relative path. Make it absolute now. */
char *cwd = xgetcwd ();
dirname = alloca (strlen (cwd) + strlen (binding->dirname) + 1);
stpcpy (stpcpy (dirname, cwd), binding->dirname);
free (cwd);
}
/* Now we have all components which describe the message catalog to be
used. Create an absolute file name. */
filename_len = strlen (dirname) + 1 + strlen (categoryvalue) + 1
+ strlen (categoryname) + 1 + strlen (domainname) + 4;
filename = (char *) xmalloc (filename_len);
sprintf (filename, "%s/%s/%s/%s.mo", dirname, categoryvalue,
categoryname, domainname);
/* Look in list of already loaded file whether it is already available. */
for (retval = _nl_loaded_domains; retval != NULL; retval = retval->next)
{
int compare = strcmp (retval->filename, filename);
if (compare == 0)
/* We found it! */
break;
if (compare < 0)
{
/* It's not in the list. */
retval = NULL;
break;
}
}
/* If it is not in list try to load it. Free the allocated FILENAME
if it is not used. */
if (retval != NULL || (retval = _nl_load_msg_cat (filename)) == NULL)
free (filename);
return retval;
}
/* Return string representation of locale CATEGORY. */
static const char *category_to_name (category)
int category;
{
const char *retval;
switch (category)
{
#ifdef LC_COLLATE
case LC_COLLATE:
retval = "LC_COLLATE";
break;
#endif
#ifdef LC_CTYPE
case LC_CTYPE:
retval = "LC_CTYPE";
break;
#endif
#ifdef LC_MONETARY
case LC_MONETARY:
retval = "LC_MONETARY";
break;
#endif
#ifdef LC_NUMERIC
case LC_NUMERIC:
retval = "LC_NUMERIC";
break;
#endif
#ifdef LC_TIME
case LC_TIME:
retval = "LC_TIME";
break;
#endif
#ifdef LC_MESSAGES
case LC_MESSAGES:
retval = "LC_MESSAGES";
break;
#endif
#ifdef LC_RESPONSE
case LC_RESPONSE:
retval = "LC_RESPONSE";
break;
#endif
#ifdef LC_ALL
case LC_ALL:
/* This might not make sense but is perhaps better than any other
value. */
retval = "LC_ALL";
break;
#endif
default:
/* If you have a better idea for a default value let me know. */
retval = "LC_XXX";
}
return retval;
}
#if !defined HAVE_SETLOCALE || !defined HAVE_LC_MESSAGES
/* Guess value of current locale from value of the environment variables. */
static const char *guess_category_value (category, categoryname)
int category;
const char *categoryname;
{
const char *retval;
/* Setting of LC_ALL overwrites all other. */
retval = getenv ("LC_ALL");
if (retval != NULL && retval[0] != '\0')
return retval;
/* Next comes the name of the desired category. */
retval = getenv (categoryname);
if (retval != NULL && retval[0] != '\0')
return retval;
/* Last possibility is the LANG environment variable. */
retval = getenv ("LANG");
if (retval != NULL && retval[0] != '\0')
return retval;
/* We use C as the default domain. POSIX says this is implementation
defined. */
return "C";
}
#endif