home *** CD-ROM | disk | FTP | other *** search
- /* 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
-