Blame locale/programs/ld-name.c

Packit Service 82fcde
/* Copyright (C) 1998-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
Packit Service 82fcde
Packit Service 82fcde
   This program is free software; you can redistribute it and/or modify
Packit Service 82fcde
   it under the terms of the GNU General Public License as published
Packit Service 82fcde
   by the Free Software Foundation; version 2 of the License, or
Packit Service 82fcde
   (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   This program is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 82fcde
   GNU General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU General Public License
Packit Service 82fcde
   along with this program; if not, see <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#ifdef HAVE_CONFIG_H
Packit Service 82fcde
# include <config.h>
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#include <langinfo.h>
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
#include <stdint.h>
Packit Service 82fcde
#include <sys/uio.h>
Packit Service 82fcde
Packit Service 82fcde
#include <assert.h>
Packit Service 82fcde
Packit Service 82fcde
#include "localedef.h"
Packit Service 82fcde
#include "localeinfo.h"
Packit Service 82fcde
#include "locfile.h"
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* The real definition of the struct for the LC_NAME locale.  */
Packit Service 82fcde
struct locale_name_t
Packit Service 82fcde
{
Packit Service 82fcde
  const char *name_fmt;
Packit Service 82fcde
  const char *name_gen;
Packit Service 82fcde
  const char *name_mr;
Packit Service 82fcde
  const char *name_mrs;
Packit Service 82fcde
  const char *name_miss;
Packit Service 82fcde
  const char *name_ms;
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
name_startup (struct linereader *lr, struct localedef_t *locale,
Packit Service 82fcde
	       int ignore_content)
Packit Service 82fcde
{
Packit Service 82fcde
  if (!ignore_content)
Packit Service 82fcde
    locale->categories[LC_NAME].name =
Packit Service 82fcde
      (struct locale_name_t *) xcalloc (1, sizeof (struct locale_name_t));
Packit Service 82fcde
Packit Service 82fcde
  if (lr != NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      lr->translate_strings = 1;
Packit Service 82fcde
      lr->return_widestr = 0;
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
void
Packit Service 82fcde
name_finish (struct localedef_t *locale, const struct charmap_t *charmap)
Packit Service 82fcde
{
Packit Service 82fcde
  struct locale_name_t *name = locale->categories[LC_NAME].name;
Packit Service 82fcde
  int nothing = 0;
Packit Service 82fcde
Packit Service 82fcde
  /* Now resolve copying and also handle completely missing definitions.  */
Packit Service 82fcde
  if (name == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      /* First see whether we were supposed to copy.  If yes, find the
Packit Service 82fcde
	 actual definition.  */
Packit Service 82fcde
      if (locale->copy_name[LC_NAME] != NULL)
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* Find the copying locale.  This has to happen transitively since
Packit Service 82fcde
	     the locale we are copying from might also copying another one.  */
Packit Service 82fcde
	  struct localedef_t *from = locale;
Packit Service 82fcde
Packit Service 82fcde
	  do
Packit Service 82fcde
	    from = find_locale (LC_NAME, from->copy_name[LC_NAME],
Packit Service 82fcde
				from->repertoire_name, charmap);
Packit Service 82fcde
	  while (from->categories[LC_NAME].name == NULL
Packit Service 82fcde
		 && from->copy_name[LC_NAME] != NULL);
Packit Service 82fcde
Packit Service 82fcde
	  name = locale->categories[LC_NAME].name
Packit Service 82fcde
	    = from->categories[LC_NAME].name;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* If there is still no definition issue an warning and create an
Packit Service 82fcde
	 empty one.  */
Packit Service 82fcde
      if (name == NULL)
Packit Service 82fcde
	{
Packit Service 82fcde
	  record_warning (_("\
Packit Service 82fcde
No definition for %s category found"), "LC_NAME");
Packit Service 82fcde
	  name_startup (NULL, locale, 0);
Packit Service 82fcde
	  name = locale->categories[LC_NAME].name;
Packit Service 82fcde
	  nothing = 1;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (name->name_fmt == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (! nothing)
Packit Service 82fcde
	record_error (0, 0, _("%s: field `%s' not defined"),
Packit Service 82fcde
		      "LC_NAME", "name_fmt");
Packit Service 82fcde
      /* Use as the default value the value of the i18n locale.  */
Packit Service 82fcde
      name->name_fmt = "%p%t%g%t%m%t%f";
Packit Service 82fcde
    }
Packit Service 82fcde
  else
Packit Service 82fcde
    {
Packit Service 82fcde
      /* We must check whether the format string contains only the
Packit Service 82fcde
	 allowed escape sequences.  */
Packit Service 82fcde
      const char *cp = name->name_fmt;
Packit Service 82fcde
Packit Service 82fcde
      if (*cp == '\0')
Packit Service 82fcde
	record_error (0, 0, _("%s: field `%s' must not be empty"),
Packit Service 82fcde
		      "LC_NAME", "name_fmt");
Packit Service 82fcde
      else
Packit Service 82fcde
	while (*cp != '\0')
Packit Service 82fcde
	  {
Packit Service 82fcde
	    if (*cp == '%')
Packit Service 82fcde
	      {
Packit Service 82fcde
		if (*++cp == 'R')
Packit Service 82fcde
		  /* Romanize-flag.  */
Packit Service 82fcde
		  ++cp;
Packit Service 82fcde
		if (strchr ("dfFgGlomMpsSt", *cp) == NULL)
Packit Service 82fcde
		  {
Packit Service 82fcde
		    record_error (0, 0, _("\
Packit Service 82fcde
%s: invalid escape sequence in field `%s'"), "LC_NAME", "name_fmt");
Packit Service 82fcde
		    break;
Packit Service 82fcde
		  }
Packit Service 82fcde
	      }
Packit Service 82fcde
	    ++cp;
Packit Service 82fcde
	  }
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
#define TEST_ELEM(cat) \
Packit Service 82fcde
  if (name->cat == NULL)						      \
Packit Service 82fcde
    {									      \
Packit Service 82fcde
      if (verbose && ! nothing)						      \
Packit Service 82fcde
	record_warning (_("%s: field `%s' not defined"), "LC_NAME", #cat);    \
Packit Service 82fcde
      name->cat = "";							      \
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  TEST_ELEM (name_gen);
Packit Service 82fcde
  TEST_ELEM (name_mr);
Packit Service 82fcde
  TEST_ELEM (name_mrs);
Packit Service 82fcde
  TEST_ELEM (name_miss);
Packit Service 82fcde
  TEST_ELEM (name_ms);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
void
Packit Service 82fcde
name_output (struct localedef_t *locale, const struct charmap_t *charmap,
Packit Service 82fcde
	     const char *output_path)
Packit Service 82fcde
{
Packit Service 82fcde
  struct locale_name_t *name = locale->categories[LC_NAME].name;
Packit Service 82fcde
  struct locale_file file;
Packit Service 82fcde
Packit Service 82fcde
  init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_NAME));
Packit Service 82fcde
  add_locale_string (&file, name->name_fmt);
Packit Service 82fcde
  add_locale_string (&file, name->name_gen);
Packit Service 82fcde
  add_locale_string (&file, name->name_mr);
Packit Service 82fcde
  add_locale_string (&file, name->name_mrs);
Packit Service 82fcde
  add_locale_string (&file, name->name_miss);
Packit Service 82fcde
  add_locale_string (&file, name->name_ms);
Packit Service 82fcde
  add_locale_string (&file, charmap->code_set_name);
Packit Service 82fcde
  write_locale_data (output_path, LC_NAME, "LC_NAME", &file;;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* The parser for the LC_NAME section of the locale definition.  */
Packit Service 82fcde
void
Packit Service 82fcde
name_read (struct linereader *ldfile, struct localedef_t *result,
Packit Service 82fcde
	   const struct charmap_t *charmap, const char *repertoire_name,
Packit Service 82fcde
	   int ignore_content)
Packit Service 82fcde
{
Packit Service 82fcde
  struct locale_name_t *name;
Packit Service 82fcde
  struct token *now;
Packit Service 82fcde
  struct token *arg;
Packit Service 82fcde
  enum token_t nowtok;
Packit Service 82fcde
Packit Service 82fcde
  /* The rest of the line containing `LC_NAME' must be empty.  */
Packit Service 82fcde
  lr_ignore_rest (ldfile, 1);
Packit Service 82fcde
Packit Service 82fcde
  do
Packit Service 82fcde
    {
Packit Service 82fcde
      now = lr_token (ldfile, charmap, result, NULL, verbose);
Packit Service 82fcde
      nowtok = now->tok;
Packit Service 82fcde
    }
Packit Service 82fcde
  while (nowtok == tok_eol);
Packit Service 82fcde
Packit Service 82fcde
  /* If we see `copy' now we are almost done.  */
Packit Service 82fcde
  if (nowtok == tok_copy)
Packit Service 82fcde
    {
Packit Service 82fcde
      handle_copy (ldfile, charmap, repertoire_name, result, tok_lc_name,
Packit Service 82fcde
		   LC_NAME, "LC_NAME", ignore_content);
Packit Service 82fcde
      return;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* Prepare the data structures.  */
Packit Service 82fcde
  name_startup (ldfile, result, ignore_content);
Packit Service 82fcde
  name = result->categories[LC_NAME].name;
Packit Service 82fcde
Packit Service 82fcde
  while (1)
Packit Service 82fcde
    {
Packit Service 82fcde
      /* Of course we don't proceed beyond the end of file.  */
Packit Service 82fcde
      if (nowtok == tok_eof)
Packit Service 82fcde
	break;
Packit Service 82fcde
Packit Service 82fcde
      /* Ignore empty lines.  */
Packit Service 82fcde
      if (nowtok == tok_eol)
Packit Service 82fcde
	{
Packit Service 82fcde
	  now = lr_token (ldfile, charmap, result, NULL, verbose);
Packit Service 82fcde
	  nowtok = now->tok;
Packit Service 82fcde
	  continue;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      switch (nowtok)
Packit Service 82fcde
	{
Packit Service 82fcde
#define STR_ELEM(cat) \
Packit Service 82fcde
	case tok_##cat:							      \
Packit Service 82fcde
	  /* Ignore the rest of the line if we don't need the input of	      \
Packit Service 82fcde
	     this line.  */						      \
Packit Service 82fcde
	  if (ignore_content)						      \
Packit Service 82fcde
	    {								      \
Packit Service 82fcde
	      lr_ignore_rest (ldfile, 0);				      \
Packit Service 82fcde
	      break;							      \
Packit Service 82fcde
	    }								      \
Packit Service 82fcde
									      \
Packit Service 82fcde
	  arg = lr_token (ldfile, charmap, result, NULL, verbose);	      \
Packit Service 82fcde
	  if (arg->tok != tok_string)					      \
Packit Service 82fcde
	    goto err_label;						      \
Packit Service 82fcde
	  if (name->cat != NULL)					      \
Packit Service 82fcde
	    lr_error (ldfile, _("%s: field `%s' declared more than once"),    \
Packit Service 82fcde
		      "LC_NAME", #cat);					      \
Packit Service 82fcde
	  else if (!ignore_content && arg->val.str.startmb == NULL)	      \
Packit Service 82fcde
	    {								      \
Packit Service 82fcde
	      lr_error (ldfile, _("%s: unknown character in field `%s'"),     \
Packit Service 82fcde
			"LC_NAME", #cat);				      \
Packit Service 82fcde
	      name->cat = "";						      \
Packit Service 82fcde
	    }								      \
Packit Service 82fcde
	  else if (!ignore_content)					      \
Packit Service 82fcde
	    name->cat = arg->val.str.startmb;				      \
Packit Service 82fcde
	  break
Packit Service 82fcde
Packit Service 82fcde
	  STR_ELEM (name_fmt);
Packit Service 82fcde
	  STR_ELEM (name_gen);
Packit Service 82fcde
	  STR_ELEM (name_mr);
Packit Service 82fcde
	  STR_ELEM (name_mrs);
Packit Service 82fcde
	  STR_ELEM (name_miss);
Packit Service 82fcde
	  STR_ELEM (name_ms);
Packit Service 82fcde
Packit Service 82fcde
	case tok_end:
Packit Service 82fcde
	  /* Next we assume `LC_NAME'.  */
Packit Service 82fcde
	  arg = lr_token (ldfile, charmap, result, NULL, verbose);
Packit Service 82fcde
	  if (arg->tok == tok_eof)
Packit Service 82fcde
	    break;
Packit Service 82fcde
	  if (arg->tok == tok_eol)
Packit Service 82fcde
	    lr_error (ldfile, _("%s: incomplete `END' line"), "LC_NAME");
Packit Service 82fcde
	  else if (arg->tok != tok_lc_name)
Packit Service 82fcde
	    lr_error (ldfile, _("\
Packit Service 82fcde
%1$s: definition does not end with `END %1$s'"), "LC_NAME");
Packit Service 82fcde
	  lr_ignore_rest (ldfile, arg->tok == tok_lc_name);
Packit Service 82fcde
	  return;
Packit Service 82fcde
Packit Service 82fcde
	default:
Packit Service 82fcde
	err_label:
Packit Service 82fcde
	  SYNTAX_ERROR (_("%s: syntax error"), "LC_NAME");
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* Prepare for the next round.  */
Packit Service 82fcde
      now = lr_token (ldfile, charmap, result, NULL, verbose);
Packit Service 82fcde
      nowtok = now->tok;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* When we come here we reached the end of the file.  */
Packit Service 82fcde
  lr_error (ldfile, _("%s: premature end of file"), "LC_NAME");
Packit Service 82fcde
}