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