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