(root)/
gcc-13.2.0/
intl/
explodename.c
       1  /* Copyright (C) 1995-1998, 2000, 2001 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 it
       5     under the terms of the GNU Library General Public License as published
       6     by 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 GNU
      12     Library General Public License for more details.
      13  
      14     You should have received a copy of the GNU Library General Public
      15     License along with this program; if not, write to the Free Software
      16     Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
      17     USA.  */
      18  
      19  #ifdef HAVE_CONFIG_H
      20  # include <config.h>
      21  #endif
      22  
      23  #include <stdlib.h>
      24  #include <string.h>
      25  #include <sys/types.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  char *
      41  _nl_find_language (name)
      42       const char *name;
      43  {
      44    while (name[0] != '\0' && name[0] != '_' && name[0] != '@'
      45  	 && name[0] != '+' && name[0] != ',')
      46      ++name;
      47  
      48    return (char *) name;
      49  }
      50  
      51  
      52  int
      53  _nl_explode_name (name, language, modifier, territory, codeset,
      54  		  normalized_codeset, special, sponsor, revision)
      55       char *name;
      56       const char **language;
      57       const char **modifier;
      58       const char **territory;
      59       const char **codeset;
      60       const char **normalized_codeset;
      61       const char **special;
      62       const char **sponsor;
      63       const char **revision;
      64  {
      65    enum { undecided, xpg, cen } syntax;
      66    char *cp;
      67    int mask;
      68  
      69    *modifier = NULL;
      70    *territory = NULL;
      71    *codeset = NULL;
      72    *normalized_codeset = NULL;
      73    *special = NULL;
      74    *sponsor = NULL;
      75    *revision = NULL;
      76  
      77    /* Now we determine the single parts of the locale name.  First
      78       look for the language.  Termination symbols are `_' and `@' if
      79       we use XPG4 style, and `_', `+', and `,' if we use CEN syntax.  */
      80    mask = 0;
      81    syntax = undecided;
      82    *language = cp = name;
      83    cp = _nl_find_language (*language);
      84  
      85    if (*language == cp)
      86      /* This does not make sense: language has to be specified.  Use
      87         this entry as it is without exploding.  Perhaps it is an alias.  */
      88      cp = strchr (*language, '\0');
      89    else if (cp[0] == '_')
      90      {
      91        /* Next is the territory.  */
      92        cp[0] = '\0';
      93        *territory = ++cp;
      94  
      95        while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@'
      96  	     && cp[0] != '+' && cp[0] != ',' && cp[0] != '_')
      97  	++cp;
      98  
      99        mask |= TERRITORY;
     100  
     101        if (cp[0] == '.')
     102  	{
     103  	  /* Next is the codeset.  */
     104  	  syntax = xpg;
     105  	  cp[0] = '\0';
     106  	  *codeset = ++cp;
     107  
     108  	  while (cp[0] != '\0' && cp[0] != '@')
     109  	    ++cp;
     110  
     111  	  mask |= XPG_CODESET;
     112  
     113  	  if (*codeset != cp && (*codeset)[0] != '\0')
     114  	    {
     115  	      *normalized_codeset = _nl_normalize_codeset (*codeset,
     116  							   cp - *codeset);
     117  	      if (strcmp (*codeset, *normalized_codeset) == 0)
     118  		free ((char *) *normalized_codeset);
     119  	      else
     120  		mask |= XPG_NORM_CODESET;
     121  	    }
     122  	}
     123      }
     124  
     125    if (cp[0] == '@' || (syntax != xpg && cp[0] == '+'))
     126      {
     127        /* Next is the modifier.  */
     128        syntax = cp[0] == '@' ? xpg : cen;
     129        cp[0] = '\0';
     130        *modifier = ++cp;
     131  
     132        while (syntax == cen && cp[0] != '\0' && cp[0] != '+'
     133  	     && cp[0] != ',' && cp[0] != '_')
     134  	++cp;
     135  
     136        mask |= XPG_MODIFIER | CEN_AUDIENCE;
     137      }
     138  
     139    if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_'))
     140      {
     141        syntax = cen;
     142  
     143        if (cp[0] == '+')
     144  	{
     145   	  /* Next is special application (CEN syntax).  */
     146  	  cp[0] = '\0';
     147  	  *special = ++cp;
     148  
     149  	  while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_')
     150  	    ++cp;
     151  
     152  	  mask |= CEN_SPECIAL;
     153  	}
     154  
     155        if (cp[0] == ',')
     156  	{
     157   	  /* Next is sponsor (CEN syntax).  */
     158  	  cp[0] = '\0';
     159  	  *sponsor = ++cp;
     160  
     161  	  while (cp[0] != '\0' && cp[0] != '_')
     162  	    ++cp;
     163  
     164  	  mask |= CEN_SPONSOR;
     165  	}
     166  
     167        if (cp[0] == '_')
     168  	{
     169   	  /* Next is revision (CEN syntax).  */
     170  	  cp[0] = '\0';
     171  	  *revision = ++cp;
     172  
     173  	  mask |= CEN_REVISION;
     174  	}
     175      }
     176  
     177    /* For CEN syntax values it might be important to have the
     178       separator character in the file name, not for XPG syntax.  */
     179    if (syntax == xpg)
     180      {
     181        if (*territory != NULL && (*territory)[0] == '\0')
     182  	mask &= ~TERRITORY;
     183  
     184        if (*codeset != NULL && (*codeset)[0] == '\0')
     185  	mask &= ~XPG_CODESET;
     186  
     187        if (*modifier != NULL && (*modifier)[0] == '\0')
     188  	mask &= ~XPG_MODIFIER;
     189      }
     190  
     191    return mask;
     192  }