Back to index

courier  0.68.2
explodename.c
Go to the documentation of this file.
00001 /* Copyright (C) 1995-1998, 2000-2001, 2003, 2005, 2007 Free Software Foundation, Inc.
00002    Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
00003 
00004    This program is free software; you can redistribute it and/or modify it
00005    under the terms of the GNU Library General Public License as published
00006    by the Free Software Foundation; either version 2, or (at your option)
00007    any later version.
00008 
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public
00015    License along with this program; if not, write to the Free Software
00016    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00017    USA.  */
00018 
00019 #ifdef HAVE_CONFIG_H
00020 # include <config.h>
00021 #endif
00022 
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <sys/types.h>
00026 
00027 #include "loadinfo.h"
00028 
00029 /* On some strange systems still no definition of NULL is found.  Sigh!  */
00030 #ifndef NULL
00031 # if defined __STDC__ && __STDC__
00032 #  define NULL ((void *) 0)
00033 # else
00034 #  define NULL 0
00035 # endif
00036 #endif
00037 
00038 /* @@ end of prolog @@ */
00039 
00040 /* Split a locale name NAME into a leading language part and all the
00041    rest.  Return a pointer to the first character after the language,
00042    i.e. to the first byte of the rest.  */
00043 static char *_nl_find_language (const char *name);
00044 
00045 static char *
00046 _nl_find_language (const char *name)
00047 {
00048   while (name[0] != '\0' && name[0] != '_' && name[0] != '@' && name[0] != '.')
00049     ++name;
00050 
00051   return (char *) name;
00052 }
00053 
00054 
00055 int
00056 _nl_explode_name (char *name,
00057                 const char **language, const char **modifier,
00058                 const char **territory, const char **codeset,
00059                 const char **normalized_codeset)
00060 {
00061   char *cp;
00062   int mask;
00063 
00064   *modifier = NULL;
00065   *territory = NULL;
00066   *codeset = NULL;
00067   *normalized_codeset = NULL;
00068 
00069   /* Now we determine the single parts of the locale name.  First
00070      look for the language.  Termination symbols are `_', '.', and `@'.  */
00071   mask = 0;
00072   *language = cp = name;
00073   cp = _nl_find_language (*language);
00074 
00075   if (*language == cp)
00076     /* This does not make sense: language has to be specified.  Use
00077        this entry as it is without exploding.  Perhaps it is an alias.  */
00078     cp = strchr (*language, '\0');
00079   else
00080     {
00081       if (cp[0] == '_')
00082        {
00083          /* Next is the territory.  */
00084          cp[0] = '\0';
00085          *territory = ++cp;
00086 
00087          while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@')
00088            ++cp;
00089 
00090          mask |= XPG_TERRITORY;
00091        }
00092 
00093       if (cp[0] == '.')
00094        {
00095          /* Next is the codeset.  */
00096          cp[0] = '\0';
00097          *codeset = ++cp;
00098 
00099          while (cp[0] != '\0' && cp[0] != '@')
00100            ++cp;
00101 
00102          mask |= XPG_CODESET;
00103 
00104          if (*codeset != cp && (*codeset)[0] != '\0')
00105            {
00106              *normalized_codeset = _nl_normalize_codeset (*codeset,
00107                                                     cp - *codeset);
00108              if (*normalized_codeset == NULL)
00109               return -1;
00110              else if (strcmp (*codeset, *normalized_codeset) == 0)
00111               free ((char *) *normalized_codeset);
00112              else
00113               mask |= XPG_NORM_CODESET;
00114            }
00115        }
00116     }
00117 
00118   if (cp[0] == '@')
00119     {
00120       /* Next is the modifier.  */
00121       cp[0] = '\0';
00122       *modifier = ++cp;
00123 
00124       if (cp[0] != '\0')
00125        mask |= XPG_MODIFIER;
00126     }
00127 
00128   if (*territory != NULL && (*territory)[0] == '\0')
00129     mask &= ~XPG_TERRITORY;
00130 
00131   if (*codeset != NULL && (*codeset)[0] == '\0')
00132     mask &= ~XPG_CODESET;
00133 
00134   return mask;
00135 }