Blame intl/explodename.c

Packit 6c4009
/* Copyright (C) 1995-2018 Free Software Foundation, Inc.
Packit 6c4009
   Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
Packit 6c4009
Packit 6c4009
   This program is free software: you can redistribute it and/or modify
Packit 6c4009
   it under the terms of the GNU Lesser General Public License as published by
Packit 6c4009
   the Free Software Foundation; either version 2.1 of the License, or
Packit 6c4009
   (at your option) any later version.
Packit 6c4009
Packit 6c4009
   This program is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 6c4009
   GNU Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public License
Packit 6c4009
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#ifdef HAVE_CONFIG_H
Packit 6c4009
# include <config.h>
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#include <stdlib.h>
Packit 6c4009
#include <string.h>
Packit 6c4009
#include <sys/types.h>
Packit 6c4009
Packit 6c4009
#include "loadinfo.h"
Packit 6c4009
Packit 6c4009
/* On some strange systems still no definition of NULL is found.  Sigh!  */
Packit 6c4009
#ifndef NULL
Packit 6c4009
# if defined __STDC__ && __STDC__
Packit 6c4009
#  define NULL ((void *) 0)
Packit 6c4009
# else
Packit 6c4009
#  define NULL 0
Packit 6c4009
# endif
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* @@ end of prolog @@ */
Packit 6c4009
Packit 6c4009
/* Split a locale name NAME into a leading language part and all the
Packit 6c4009
   rest.  Return a pointer to the first character after the language,
Packit 6c4009
   i.e. to the first byte of the rest.  */
Packit 6c4009
static char *_nl_find_language (const char *name);
Packit 6c4009
Packit 6c4009
static char *
Packit 6c4009
_nl_find_language (const char *name)
Packit 6c4009
{
Packit 6c4009
  while (name[0] != '\0' && name[0] != '_' && name[0] != '@' && name[0] != '.')
Packit 6c4009
    ++name;
Packit 6c4009
Packit 6c4009
  return (char *) name;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
_nl_explode_name (char *name,
Packit 6c4009
		  const char **language, const char **modifier,
Packit 6c4009
		  const char **territory, const char **codeset,
Packit 6c4009
		  const char **normalized_codeset)
Packit 6c4009
{
Packit 6c4009
  char *cp;
Packit 6c4009
  int mask;
Packit 6c4009
Packit 6c4009
  *modifier = NULL;
Packit 6c4009
  *territory = NULL;
Packit 6c4009
  *codeset = NULL;
Packit 6c4009
  *normalized_codeset = NULL;
Packit 6c4009
Packit 6c4009
  /* Now we determine the single parts of the locale name.  First
Packit 6c4009
     look for the language.  Termination symbols are `_', '.', and `@'.  */
Packit 6c4009
  mask = 0;
Packit 6c4009
  *language = cp = name;
Packit 6c4009
  cp = _nl_find_language (*language);
Packit 6c4009
Packit 6c4009
  if (*language == cp)
Packit 6c4009
    /* This does not make sense: language has to be specified.  Use
Packit 6c4009
       this entry as it is without exploding.  Perhaps it is an alias.  */
Packit 6c4009
    cp = strchr (*language, '\0');
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      if (cp[0] == '_')
Packit 6c4009
	{
Packit 6c4009
	  /* Next is the territory.  */
Packit 6c4009
	  cp[0] = '\0';
Packit 6c4009
	  *territory = ++cp;
Packit 6c4009
Packit 6c4009
	  while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@')
Packit 6c4009
	    ++cp;
Packit 6c4009
Packit 6c4009
	  mask |= XPG_TERRITORY;
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
      if (cp[0] == '.')
Packit 6c4009
	{
Packit 6c4009
	  /* Next is the codeset.  */
Packit 6c4009
	  cp[0] = '\0';
Packit 6c4009
	  *codeset = ++cp;
Packit 6c4009
Packit 6c4009
	  while (cp[0] != '\0' && cp[0] != '@')
Packit 6c4009
	    ++cp;
Packit 6c4009
Packit 6c4009
	  mask |= XPG_CODESET;
Packit 6c4009
Packit 6c4009
	  if (*codeset != cp && (*codeset)[0] != '\0')
Packit 6c4009
	    {
Packit 6c4009
	      *normalized_codeset = _nl_normalize_codeset (*codeset,
Packit 6c4009
							   cp - *codeset);
Packit 6c4009
	      if (*normalized_codeset == NULL)
Packit 6c4009
		return -1;
Packit 6c4009
	      else if (strcmp (*codeset, *normalized_codeset) == 0)
Packit 6c4009
		free ((char *) *normalized_codeset);
Packit 6c4009
	      else
Packit 6c4009
		mask |= XPG_NORM_CODESET;
Packit 6c4009
	    }
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  if (cp[0] == '@')
Packit 6c4009
    {
Packit 6c4009
      /* Next is the modifier.  */
Packit 6c4009
      cp[0] = '\0';
Packit 6c4009
      *modifier = ++cp;
Packit 6c4009
Packit 6c4009
      if (cp[0] != '\0')
Packit 6c4009
	mask |= XPG_MODIFIER;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  if (*territory != NULL && (*territory)[0] == '\0')
Packit 6c4009
    mask &= ~XPG_TERRITORY;
Packit 6c4009
Packit 6c4009
  if (*codeset != NULL && (*codeset)[0] == '\0')
Packit 6c4009
    mask &= ~XPG_CODESET;
Packit 6c4009
Packit 6c4009
  return mask;
Packit 6c4009
}