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