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