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 >
C/C++ Source or Header  |  1996-09-28  |  6KB  |  238 lines

  1. /* finddomain.c -- handle list of needed message catalogs
  2.    Copyright (C) 1995 Software Foundation, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #ifdef HAVE_CONFIG_H
  19. # include <config.h>
  20. #endif
  21.  
  22. #ifdef HAVE_ALLOCA_H
  23. #include <alloca.h>
  24. #endif
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28.  
  29. #include "gettext.h"
  30. #include "gettextP.h"
  31. #include "libgettext.h"
  32.  
  33. /* @@ end of prolog @@ */
  34.  
  35. /* Contains the default location of the message catalogs.  */
  36. const char _nl_default_dirname[] = DEF_MSG_DOM_DIR;
  37.  
  38. /* List with bindings of specific domains created by bindtextdomain()
  39.    calls.  */
  40. struct binding *_nl_domain_bindings;
  41.  
  42. /* List of already loaded domains.  */
  43. extern struct loaded_domain *_nl_loaded_domains;
  44.  
  45. /* Prototypes for library functions.  */
  46. char *xgetcwd ();
  47. void *xmalloc ();
  48.  
  49. /* Prototypes for local functions.  */
  50. static const char *category_to_name __P((int category));
  51. #if !defined HAVE_SETLOCALE || !defined HAVE_LC_MESSAGES
  52. static const char *guess_category_value __P((int category,
  53.                          const char *categoryname));
  54. #endif
  55.  
  56.  
  57. /* Return a data structure describing the message catalog described by
  58.    the DOMAINNAME and CATEGORY parameters with respect to the currently
  59.    established bindings.  */
  60. struct loaded_domain *
  61. _nl_find_domain (domainname, category)
  62.      const char *domainname;
  63.      int category;
  64. {
  65.   const char *categoryname;
  66.   const char *categoryvalue;
  67.   struct binding *binding;
  68.   char *dirname;
  69.   char *filename;
  70.   size_t filename_len;
  71.   struct loaded_domain *retval;
  72.  
  73.   /* Now determine the symbolic name of CATEGORY and its value.  */
  74.   categoryname = category_to_name (category);
  75. #ifdef HAVE_SETLOCALE
  76. # ifndef HAVE_LC_MESSAGES
  77.   if (category == LC_MESSAGES)
  78.     categoryvalue = guess_category_value (category, categoryname);
  79.   else
  80. # endif
  81.     categoryvalue = setlocale (category, NULL);
  82. #else
  83.   categoryvalue = guess_category_value (category, categoryname);
  84. #endif
  85.  
  86.   /* If the current locale value is C (or POSIX) we don't load a domain.
  87.      The causes the calling function to return the MSGID.  */ 
  88.   if (strcmp (categoryvalue, "C") == 0 || strcmp (categoryvalue, "POSIX") == 0)
  89.     return NULL;
  90.  
  91.   /* First find matching binding.  */
  92.   for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
  93.     {
  94.       int compare = strcmp (domainname, binding->domainname);
  95.       if (compare == 0)
  96.     /* We found it!  */
  97.     break;
  98.       if (compare < 0)
  99.     {
  100.       /* It is not in the list.  */
  101.       binding = NULL;
  102.       break;
  103.     }
  104.     }
  105.  
  106.   if (binding == NULL)
  107.     dirname = (char *) _nl_default_dirname;
  108.   else if (binding->dirname[0] == '/')
  109.     dirname = binding->dirname;
  110.   else
  111.     {
  112.       /* We have a relative path.  Make it absolute now.  */
  113.       char *cwd = xgetcwd ();
  114.  
  115.       dirname = alloca (strlen (cwd) + strlen (binding->dirname) + 1);
  116.       stpcpy (stpcpy (dirname, cwd), binding->dirname);
  117.  
  118.       free (cwd);
  119.     }
  120.  
  121.   /* Now we have all components which describe the message catalog to be
  122.      used.  Create an absolute file name.  */
  123.   filename_len = strlen (dirname) + 1 + strlen (categoryvalue) + 1
  124.          + strlen (categoryname) + 1 + strlen (domainname) + 4;
  125.   filename = (char *) xmalloc (filename_len);
  126.   sprintf (filename, "%s/%s/%s/%s.mo", dirname, categoryvalue,
  127.        categoryname, domainname);
  128.  
  129.   /* Look in list of already loaded file whether it is already available.  */
  130.   for (retval = _nl_loaded_domains; retval != NULL; retval = retval->next)
  131.     {
  132.       int compare = strcmp (retval->filename, filename);
  133.       if (compare == 0)
  134.     /* We found it!  */
  135.     break;
  136.       if (compare < 0)
  137.     {
  138.       /* It's not in the list.  */
  139.       retval = NULL;
  140.       break;
  141.     }
  142.     }
  143.  
  144.   /* If it is not in list try to load it.  Free the allocated FILENAME
  145.      if it is not used.  */
  146.   if (retval != NULL || (retval = _nl_load_msg_cat (filename)) == NULL)
  147.     free (filename);
  148.  
  149.   return retval;
  150. }
  151.  
  152. /* Return string representation of locale CATEGORY.  */
  153. static const char *category_to_name (category)
  154.      int category;
  155. {
  156.   const char *retval;
  157.  
  158.   switch (category)
  159.   {
  160. #ifdef LC_COLLATE
  161.   case LC_COLLATE:
  162.     retval = "LC_COLLATE";
  163.     break;
  164. #endif
  165. #ifdef LC_CTYPE
  166.   case LC_CTYPE:
  167.     retval = "LC_CTYPE";
  168.     break;
  169. #endif
  170. #ifdef LC_MONETARY
  171.   case LC_MONETARY:
  172.     retval = "LC_MONETARY";
  173.     break;
  174. #endif
  175. #ifdef LC_NUMERIC
  176.   case LC_NUMERIC:
  177.     retval = "LC_NUMERIC";
  178.     break;
  179. #endif
  180. #ifdef LC_TIME
  181.   case LC_TIME:
  182.     retval = "LC_TIME";
  183.     break;
  184. #endif
  185. #ifdef LC_MESSAGES
  186.   case LC_MESSAGES:
  187.     retval = "LC_MESSAGES";
  188.     break;
  189. #endif
  190. #ifdef LC_RESPONSE
  191.   case LC_RESPONSE:
  192.     retval = "LC_RESPONSE";
  193.     break;
  194. #endif
  195. #ifdef LC_ALL
  196.   case LC_ALL:
  197.     /* This might not make sense but is perhaps better than any other
  198.        value.  */
  199.     retval = "LC_ALL";
  200.     break;
  201. #endif
  202.   default:
  203.     /* If you have a better idea for a default value let me know.  */
  204.     retval = "LC_XXX";
  205.   }
  206.  
  207.   return retval;
  208. }
  209.  
  210. #if !defined HAVE_SETLOCALE || !defined HAVE_LC_MESSAGES
  211. /* Guess value of current locale from value of the environment variables.  */
  212. static const char *guess_category_value (category, categoryname)
  213.      int category;
  214.      const char *categoryname;
  215. {
  216.   const char *retval;
  217.  
  218.   /* Setting of LC_ALL overwrites all other.  */
  219.   retval = getenv ("LC_ALL");
  220.   if (retval != NULL && retval[0] != '\0')
  221.     return retval;
  222.  
  223.   /* Next comes the name of the desired category.  */
  224.   retval = getenv (categoryname);
  225.   if (retval != NULL && retval[0] != '\0')
  226.     return retval;
  227.  
  228.   /* Last possibility is the LANG environment variable.  */
  229.   retval = getenv ("LANG");
  230.   if (retval != NULL && retval[0] != '\0')
  231.     return retval;
  232.  
  233.   /* We use C as the default domain.  POSIX says this is implementation
  234.      defined.  */
  235.   return "C";
  236. }
  237. #endif
  238.