xref: /netbsd-src/external/gpl2/gettext/dist/gettext-runtime/intl/explodename.c (revision 946379e7b37692fc43f68eb0d1c10daa0a7f3b6c)
1*946379e7Schristos /* Copyright (C) 1995-1998, 2000-2001, 2003, 2005 Free Software Foundation, Inc.
2*946379e7Schristos    Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
3*946379e7Schristos 
4*946379e7Schristos    This program is free software; you can redistribute it and/or modify it
5*946379e7Schristos    under the terms of the GNU Library General Public License as published
6*946379e7Schristos    by the Free Software Foundation; either version 2, or (at your option)
7*946379e7Schristos    any later version.
8*946379e7Schristos 
9*946379e7Schristos    This program is distributed in the hope that it will be useful,
10*946379e7Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
11*946379e7Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12*946379e7Schristos    Library General Public License for more details.
13*946379e7Schristos 
14*946379e7Schristos    You should have received a copy of the GNU Library General Public
15*946379e7Schristos    License along with this program; if not, write to the Free Software
16*946379e7Schristos    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
17*946379e7Schristos    USA.  */
18*946379e7Schristos 
19*946379e7Schristos #ifdef HAVE_CONFIG_H
20*946379e7Schristos # include <config.h>
21*946379e7Schristos #endif
22*946379e7Schristos 
23*946379e7Schristos #include <stdlib.h>
24*946379e7Schristos #include <string.h>
25*946379e7Schristos #include <sys/types.h>
26*946379e7Schristos 
27*946379e7Schristos #include "loadinfo.h"
28*946379e7Schristos 
29*946379e7Schristos /* On some strange systems still no definition of NULL is found.  Sigh!  */
30*946379e7Schristos #ifndef NULL
31*946379e7Schristos # if defined __STDC__ && __STDC__
32*946379e7Schristos #  define NULL ((void *) 0)
33*946379e7Schristos # else
34*946379e7Schristos #  define NULL 0
35*946379e7Schristos # endif
36*946379e7Schristos #endif
37*946379e7Schristos 
38*946379e7Schristos /* @@ end of prolog @@ */
39*946379e7Schristos 
40*946379e7Schristos /* Split a locale name NAME into a leading language part and all the
41*946379e7Schristos    rest.  Return a pointer to the first character after the language,
42*946379e7Schristos    i.e. to the first byte of the rest.  */
43*946379e7Schristos static char *_nl_find_language (const char *name);
44*946379e7Schristos 
45*946379e7Schristos static char *
_nl_find_language(const char * name)46*946379e7Schristos _nl_find_language (const char *name)
47*946379e7Schristos {
48*946379e7Schristos   while (name[0] != '\0' && name[0] != '_' && name[0] != '@' && name[0] != '.')
49*946379e7Schristos     ++name;
50*946379e7Schristos 
51*946379e7Schristos   return (char *) name;
52*946379e7Schristos }
53*946379e7Schristos 
54*946379e7Schristos 
55*946379e7Schristos int
_nl_explode_name(char * name,const char ** language,const char ** modifier,const char ** territory,const char ** codeset,const char ** normalized_codeset)56*946379e7Schristos _nl_explode_name (char *name,
57*946379e7Schristos 		  const char **language, const char **modifier,
58*946379e7Schristos 		  const char **territory, const char **codeset,
59*946379e7Schristos 		  const char **normalized_codeset)
60*946379e7Schristos {
61*946379e7Schristos   char *cp;
62*946379e7Schristos   int mask;
63*946379e7Schristos 
64*946379e7Schristos   *modifier = NULL;
65*946379e7Schristos   *territory = NULL;
66*946379e7Schristos   *codeset = NULL;
67*946379e7Schristos   *normalized_codeset = NULL;
68*946379e7Schristos 
69*946379e7Schristos   /* Now we determine the single parts of the locale name.  First
70*946379e7Schristos      look for the language.  Termination symbols are `_', '.', and `@'.  */
71*946379e7Schristos   mask = 0;
72*946379e7Schristos   *language = cp = name;
73*946379e7Schristos   cp = _nl_find_language (*language);
74*946379e7Schristos 
75*946379e7Schristos   if (*language == cp)
76*946379e7Schristos     /* This does not make sense: language has to be specified.  Use
77*946379e7Schristos        this entry as it is without exploding.  Perhaps it is an alias.  */
78*946379e7Schristos     cp = strchr (*language, '\0');
79*946379e7Schristos   else
80*946379e7Schristos     {
81*946379e7Schristos       if (cp[0] == '_')
82*946379e7Schristos 	{
83*946379e7Schristos 	  /* Next is the territory.  */
84*946379e7Schristos 	  cp[0] = '\0';
85*946379e7Schristos 	  *territory = ++cp;
86*946379e7Schristos 
87*946379e7Schristos 	  while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@')
88*946379e7Schristos 	    ++cp;
89*946379e7Schristos 
90*946379e7Schristos 	  mask |= XPG_TERRITORY;
91*946379e7Schristos 	}
92*946379e7Schristos 
93*946379e7Schristos       if (cp[0] == '.')
94*946379e7Schristos 	{
95*946379e7Schristos 	  /* Next is the codeset.  */
96*946379e7Schristos 	  cp[0] = '\0';
97*946379e7Schristos 	  *codeset = ++cp;
98*946379e7Schristos 
99*946379e7Schristos 	  while (cp[0] != '\0' && cp[0] != '@')
100*946379e7Schristos 	    ++cp;
101*946379e7Schristos 
102*946379e7Schristos 	  mask |= XPG_CODESET;
103*946379e7Schristos 
104*946379e7Schristos 	  if (*codeset != cp && (*codeset)[0] != '\0')
105*946379e7Schristos 	    {
106*946379e7Schristos 	      *normalized_codeset = _nl_normalize_codeset (*codeset,
107*946379e7Schristos 							   cp - *codeset);
108*946379e7Schristos 	      if (strcmp (*codeset, *normalized_codeset) == 0)
109*946379e7Schristos 		free ((char *) *normalized_codeset);
110*946379e7Schristos 	      else
111*946379e7Schristos 		mask |= XPG_NORM_CODESET;
112*946379e7Schristos 	    }
113*946379e7Schristos 	}
114*946379e7Schristos     }
115*946379e7Schristos 
116*946379e7Schristos   if (cp[0] == '@')
117*946379e7Schristos     {
118*946379e7Schristos       /* Next is the modifier.  */
119*946379e7Schristos       cp[0] = '\0';
120*946379e7Schristos       *modifier = ++cp;
121*946379e7Schristos 
122*946379e7Schristos       if (cp[0] != '\0')
123*946379e7Schristos 	mask |= XPG_MODIFIER;
124*946379e7Schristos     }
125*946379e7Schristos 
126*946379e7Schristos   if (*territory != NULL && (*territory)[0] == '\0')
127*946379e7Schristos     mask &= ~XPG_TERRITORY;
128*946379e7Schristos 
129*946379e7Schristos   if (*codeset != NULL && (*codeset)[0] == '\0')
130*946379e7Schristos     mask &= ~XPG_CODESET;
131*946379e7Schristos 
132*946379e7Schristos   return mask;
133*946379e7Schristos }
134