xref: /openbsd-src/gnu/usr.bin/binutils-2.17/intl/explodename.c (revision 3d8817e467ea46cf4772788d6804dd293abfb01a)
1*3d8817e4Smiod /* Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
2*3d8817e4Smiod    Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
3*3d8817e4Smiod 
4*3d8817e4Smiod    This program is free software; you can redistribute it and/or modify
5*3d8817e4Smiod    it under the terms of the GNU General Public License as published by
6*3d8817e4Smiod    the Free Software Foundation; either version 2, or (at your option)
7*3d8817e4Smiod    any later version.
8*3d8817e4Smiod 
9*3d8817e4Smiod    This program is distributed in the hope that it will be useful,
10*3d8817e4Smiod    but WITHOUT ANY WARRANTY; without even the implied warranty of
11*3d8817e4Smiod    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12*3d8817e4Smiod    GNU General Public License for more details.
13*3d8817e4Smiod 
14*3d8817e4Smiod    You should have received a copy of the GNU General Public License
15*3d8817e4Smiod    along with this program; if not, write to the Free Software Foundation,
16*3d8817e4Smiod    Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
17*3d8817e4Smiod 
18*3d8817e4Smiod #ifdef HAVE_CONFIG_H
19*3d8817e4Smiod # include <config.h>
20*3d8817e4Smiod #endif
21*3d8817e4Smiod 
22*3d8817e4Smiod #if defined STDC_HEADERS || defined _LIBC
23*3d8817e4Smiod # include <stdlib.h>
24*3d8817e4Smiod #endif
25*3d8817e4Smiod 
26*3d8817e4Smiod #if defined HAVE_STRING_H || defined _LIBC
27*3d8817e4Smiod # include <string.h>
28*3d8817e4Smiod #else
29*3d8817e4Smiod # include <strings.h>
30*3d8817e4Smiod #endif
31*3d8817e4Smiod #include <sys/types.h>
32*3d8817e4Smiod 
33*3d8817e4Smiod #include "loadinfo.h"
34*3d8817e4Smiod 
35*3d8817e4Smiod /* On some strange systems still no definition of NULL is found.  Sigh!  */
36*3d8817e4Smiod #ifndef NULL
37*3d8817e4Smiod # if defined __STDC__ && __STDC__
38*3d8817e4Smiod #  define NULL ((void *) 0)
39*3d8817e4Smiod # else
40*3d8817e4Smiod #  define NULL 0
41*3d8817e4Smiod # endif
42*3d8817e4Smiod #endif
43*3d8817e4Smiod 
44*3d8817e4Smiod /* @@ end of prolog @@ */
45*3d8817e4Smiod 
46*3d8817e4Smiod int
_nl_explode_name(name,language,modifier,territory,codeset,normalized_codeset,special,sponsor,revision)47*3d8817e4Smiod _nl_explode_name (name, language, modifier, territory, codeset,
48*3d8817e4Smiod 		  normalized_codeset, special, sponsor, revision)
49*3d8817e4Smiod      char *name;
50*3d8817e4Smiod      const char **language;
51*3d8817e4Smiod      const char **modifier;
52*3d8817e4Smiod      const char **territory;
53*3d8817e4Smiod      const char **codeset;
54*3d8817e4Smiod      const char **normalized_codeset;
55*3d8817e4Smiod      const char **special;
56*3d8817e4Smiod      const char **sponsor;
57*3d8817e4Smiod      const char **revision;
58*3d8817e4Smiod {
59*3d8817e4Smiod   enum { undecided, xpg, cen } syntax;
60*3d8817e4Smiod   char *cp;
61*3d8817e4Smiod   int mask;
62*3d8817e4Smiod 
63*3d8817e4Smiod   *modifier = NULL;
64*3d8817e4Smiod   *territory = NULL;
65*3d8817e4Smiod   *codeset = NULL;
66*3d8817e4Smiod   *normalized_codeset = NULL;
67*3d8817e4Smiod   *special = NULL;
68*3d8817e4Smiod   *sponsor = NULL;
69*3d8817e4Smiod   *revision = NULL;
70*3d8817e4Smiod 
71*3d8817e4Smiod   /* Now we determine the single parts of the locale name.  First
72*3d8817e4Smiod      look for the language.  Termination symbols are `_' and `@' if
73*3d8817e4Smiod      we use XPG4 style, and `_', `+', and `,' if we use CEN syntax.  */
74*3d8817e4Smiod   mask = 0;
75*3d8817e4Smiod   syntax = undecided;
76*3d8817e4Smiod   *language = cp = name;
77*3d8817e4Smiod   while (cp[0] != '\0' && cp[0] != '_' && cp[0] != '@'
78*3d8817e4Smiod 	 && cp[0] != '+' && cp[0] != ',')
79*3d8817e4Smiod     ++cp;
80*3d8817e4Smiod 
81*3d8817e4Smiod   if (*language == cp)
82*3d8817e4Smiod     /* This does not make sense: language has to be specified.  Use
83*3d8817e4Smiod        this entry as it is without exploding.  Perhaps it is an alias.  */
84*3d8817e4Smiod     cp = strchr (*language, '\0');
85*3d8817e4Smiod   else if (cp[0] == '_')
86*3d8817e4Smiod     {
87*3d8817e4Smiod       /* Next is the territory.  */
88*3d8817e4Smiod       cp[0] = '\0';
89*3d8817e4Smiod       *territory = ++cp;
90*3d8817e4Smiod 
91*3d8817e4Smiod       while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@'
92*3d8817e4Smiod 	     && cp[0] != '+' && cp[0] != ',' && cp[0] != '_')
93*3d8817e4Smiod 	++cp;
94*3d8817e4Smiod 
95*3d8817e4Smiod       mask |= TERRITORY;
96*3d8817e4Smiod 
97*3d8817e4Smiod       if (cp[0] == '.')
98*3d8817e4Smiod 	{
99*3d8817e4Smiod 	  /* Next is the codeset.  */
100*3d8817e4Smiod 	  syntax = xpg;
101*3d8817e4Smiod 	  cp[0] = '\0';
102*3d8817e4Smiod 	  *codeset = ++cp;
103*3d8817e4Smiod 
104*3d8817e4Smiod 	  while (cp[0] != '\0' && cp[0] != '@')
105*3d8817e4Smiod 	    ++cp;
106*3d8817e4Smiod 
107*3d8817e4Smiod 	  mask |= XPG_CODESET;
108*3d8817e4Smiod 
109*3d8817e4Smiod 	  if (*codeset != cp && (*codeset)[0] != '\0')
110*3d8817e4Smiod 	    {
111*3d8817e4Smiod 	      *normalized_codeset = _nl_normalize_codeset (*codeset,
112*3d8817e4Smiod 							   cp - *codeset);
113*3d8817e4Smiod 	      if (strcmp (*codeset, *normalized_codeset) == 0)
114*3d8817e4Smiod 		free ((char *) *normalized_codeset);
115*3d8817e4Smiod 	      else
116*3d8817e4Smiod 		mask |= XPG_NORM_CODESET;
117*3d8817e4Smiod 	    }
118*3d8817e4Smiod 	}
119*3d8817e4Smiod     }
120*3d8817e4Smiod 
121*3d8817e4Smiod   if (cp[0] == '@' || (syntax != xpg && cp[0] == '+'))
122*3d8817e4Smiod     {
123*3d8817e4Smiod       /* Next is the modifier.  */
124*3d8817e4Smiod       syntax = cp[0] == '@' ? xpg : cen;
125*3d8817e4Smiod       cp[0] = '\0';
126*3d8817e4Smiod       *modifier = ++cp;
127*3d8817e4Smiod 
128*3d8817e4Smiod       while (syntax == cen && cp[0] != '\0' && cp[0] != '+'
129*3d8817e4Smiod 	     && cp[0] != ',' && cp[0] != '_')
130*3d8817e4Smiod 	++cp;
131*3d8817e4Smiod 
132*3d8817e4Smiod       mask |= XPG_MODIFIER | CEN_AUDIENCE;
133*3d8817e4Smiod     }
134*3d8817e4Smiod 
135*3d8817e4Smiod   if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_'))
136*3d8817e4Smiod     {
137*3d8817e4Smiod       syntax = cen;
138*3d8817e4Smiod 
139*3d8817e4Smiod       if (cp[0] == '+')
140*3d8817e4Smiod 	{
141*3d8817e4Smiod  	  /* Next is special application (CEN syntax).  */
142*3d8817e4Smiod 	  cp[0] = '\0';
143*3d8817e4Smiod 	  *special = ++cp;
144*3d8817e4Smiod 
145*3d8817e4Smiod 	  while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_')
146*3d8817e4Smiod 	    ++cp;
147*3d8817e4Smiod 
148*3d8817e4Smiod 	  mask |= CEN_SPECIAL;
149*3d8817e4Smiod 	}
150*3d8817e4Smiod 
151*3d8817e4Smiod       if (cp[0] == ',')
152*3d8817e4Smiod 	{
153*3d8817e4Smiod  	  /* Next is sponsor (CEN syntax).  */
154*3d8817e4Smiod 	  cp[0] = '\0';
155*3d8817e4Smiod 	  *sponsor = ++cp;
156*3d8817e4Smiod 
157*3d8817e4Smiod 	  while (cp[0] != '\0' && cp[0] != '_')
158*3d8817e4Smiod 	    ++cp;
159*3d8817e4Smiod 
160*3d8817e4Smiod 	  mask |= CEN_SPONSOR;
161*3d8817e4Smiod 	}
162*3d8817e4Smiod 
163*3d8817e4Smiod       if (cp[0] == '_')
164*3d8817e4Smiod 	{
165*3d8817e4Smiod  	  /* Next is revision (CEN syntax).  */
166*3d8817e4Smiod 	  cp[0] = '\0';
167*3d8817e4Smiod 	  *revision = ++cp;
168*3d8817e4Smiod 
169*3d8817e4Smiod 	  mask |= CEN_REVISION;
170*3d8817e4Smiod 	}
171*3d8817e4Smiod     }
172*3d8817e4Smiod 
173*3d8817e4Smiod   /* For CEN syntax values it might be important to have the
174*3d8817e4Smiod      separator character in the file name, not for XPG syntax.  */
175*3d8817e4Smiod   if (syntax == xpg)
176*3d8817e4Smiod     {
177*3d8817e4Smiod       if (*territory != NULL && (*territory)[0] == '\0')
178*3d8817e4Smiod 	mask &= ~TERRITORY;
179*3d8817e4Smiod 
180*3d8817e4Smiod       if (*codeset != NULL && (*codeset)[0] == '\0')
181*3d8817e4Smiod 	mask &= ~XPG_CODESET;
182*3d8817e4Smiod 
183*3d8817e4Smiod       if (*modifier != NULL && (*modifier)[0] == '\0')
184*3d8817e4Smiod 	mask &= ~XPG_MODIFIER;
185*3d8817e4Smiod     }
186*3d8817e4Smiod 
187*3d8817e4Smiod   return mask;
188*3d8817e4Smiod }
189