Blame locale/programs/ld-address.c

Packit 6c4009
/* Copyright (C) 1998-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
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 General Public License as published
Packit 6c4009
   by the Free Software Foundation; version 2 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 General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU 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 <byteswap.h>
Packit 6c4009
#include <langinfo.h>
Packit 6c4009
#include <string.h>
Packit 6c4009
#include <stdint.h>
Packit 6c4009
#include <sys/uio.h>
Packit 6c4009
Packit 6c4009
#include <assert.h>
Packit 6c4009
Packit 6c4009
#include "localedef.h"
Packit 6c4009
#include "localeinfo.h"
Packit 6c4009
#include "locfile.h"
Packit 6c4009
Packit 6c4009
Packit 6c4009
static struct
Packit 6c4009
{
Packit 6c4009
  const char ab2[3];
Packit 6c4009
  const char ab3[4];
Packit 6c4009
  uint32_t num;
Packit 6c4009
} iso3166[] =
Packit 6c4009
{
Packit 6c4009
#define DEFINE_COUNTRY_CODE(Name, Ab2, Ab3, Num) \
Packit 6c4009
  { #Ab2, #Ab3, Num },
Packit 6c4009
#include "iso-3166.def"
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
Packit 6c4009
static struct
Packit 6c4009
{
Packit 6c4009
  const char ab[3];
Packit 6c4009
  const char term[4];
Packit 6c4009
  const char lib[4];
Packit 6c4009
} iso639[] =
Packit 6c4009
{
Packit 6c4009
#define DEFINE_LANGUAGE_CODE(Name, Ab, Term, Lib) \
Packit 6c4009
  { #Ab, #Term, #Lib },
Packit 6c4009
#define DEFINE_LANGUAGE_CODE3(Name, Term, Lib) \
Packit 6c4009
  { "", #Term, #Lib },
Packit 6c4009
#define DEFINE_LANGUAGE_CODE2(Name, Term) \
Packit 6c4009
  { "", #Term, "" },
Packit 6c4009
#include "iso-639.def"
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* The real definition of the struct for the LC_ADDRESS locale.  */
Packit 6c4009
struct locale_address_t
Packit 6c4009
{
Packit 6c4009
  const char *postal_fmt;
Packit 6c4009
  const char *country_name;
Packit 6c4009
  const char *country_post;
Packit 6c4009
  const char *country_ab2;
Packit 6c4009
  const char *country_ab3;
Packit 6c4009
  uint32_t country_num;
Packit 6c4009
  const char *country_car;
Packit 6c4009
  const char *country_isbn;
Packit 6c4009
  const char *lang_name;
Packit 6c4009
  const char *lang_ab;
Packit 6c4009
  const char *lang_term;
Packit 6c4009
  const char *lang_lib;
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
address_startup (struct linereader *lr, struct localedef_t *locale,
Packit 6c4009
		 int ignore_content)
Packit 6c4009
{
Packit 6c4009
  if (!ignore_content)
Packit 6c4009
    locale->categories[LC_ADDRESS].address =
Packit 6c4009
      (struct locale_address_t *) xcalloc (1,
Packit 6c4009
					   sizeof (struct locale_address_t));
Packit 6c4009
Packit 6c4009
  if (lr != NULL)
Packit 6c4009
    {
Packit 6c4009
      lr->translate_strings = 1;
Packit 6c4009
      lr->return_widestr = 0;
Packit 6c4009
    }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
address_finish (struct localedef_t *locale, const struct charmap_t *charmap)
Packit 6c4009
{
Packit 6c4009
  struct locale_address_t *address = locale->categories[LC_ADDRESS].address;
Packit 6c4009
  size_t cnt;
Packit 6c4009
  int helper;
Packit 6c4009
  int nothing = 0;
Packit 6c4009
Packit 6c4009
  /* Now resolve copying and also handle completely missing definitions.  */
Packit 6c4009
  if (address == NULL)
Packit 6c4009
    {
Packit 6c4009
      /* First see whether we were supposed to copy.  If yes, find the
Packit 6c4009
	 actual definition.  */
Packit 6c4009
      if (locale->copy_name[LC_ADDRESS] != NULL)
Packit 6c4009
	{
Packit 6c4009
	  /* Find the copying locale.  This has to happen transitively since
Packit 6c4009
	     the locale we are copying from might also copying another one.  */
Packit 6c4009
	  struct localedef_t *from = locale;
Packit 6c4009
Packit 6c4009
	  do
Packit 6c4009
	    from = find_locale (LC_ADDRESS, from->copy_name[LC_ADDRESS],
Packit 6c4009
				from->repertoire_name, charmap);
Packit 6c4009
	  while (from->categories[LC_ADDRESS].address == NULL
Packit 6c4009
		 && from->copy_name[LC_ADDRESS] != NULL);
Packit 6c4009
Packit 6c4009
	  address = locale->categories[LC_ADDRESS].address
Packit 6c4009
	    = from->categories[LC_ADDRESS].address;
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
      /* If there is still no definition issue an warning and create an
Packit 6c4009
	 empty one.  */
Packit 6c4009
      if (address == NULL)
Packit 6c4009
	{
Packit 6c4009
	  record_warning (_("\
Packit 6c4009
No definition for %s category found"), "LC_ADDRESS");
Packit 6c4009
	  address_startup (NULL, locale, 0);
Packit 6c4009
	  address = locale->categories[LC_ADDRESS].address;
Packit 6c4009
	  nothing = 1;
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  if (address->postal_fmt == NULL)
Packit 6c4009
    {
Packit 6c4009
      if (! nothing)
Packit 6c4009
	record_error (0, 0, _("%s: field `%s' not defined"),
Packit 6c4009
		      "LC_ADDRESS", "postal_fmt");
Packit 6c4009
      /* Use as the default value the value of the i18n locale.  */
Packit 6c4009
      address->postal_fmt = "%a%N%f%N%d%N%b%N%s %h %e %r%N%C-%z %T%N%c%N";
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      /* We must check whether the format string contains only the allowed
Packit 6c4009
	 escape sequences.  Last checked against ISO 30112 WD10 [2014]. */
Packit 6c4009
      const char *cp = address->postal_fmt;
Packit 6c4009
Packit 6c4009
      if (*cp == '\0')
Packit 6c4009
	record_error (0, 0, _("%s: field `%s' must not be empty"),
Packit 6c4009
		      "LC_ADDRESS", "postal_fmt");
Packit 6c4009
      else
Packit 6c4009
	while (*cp != '\0')
Packit 6c4009
	  {
Packit 6c4009
	    if (*cp == '%')
Packit 6c4009
	      {
Packit 6c4009
		if (*++cp == 'R')
Packit 6c4009
		  /* Romanize-flag.  */
Packit 6c4009
		  ++cp;
Packit 6c4009
		if (strchr ("nafdbshNtreClzTSc%", *cp) == NULL)
Packit 6c4009
		  {
Packit 6c4009
		    record_error (0, 0, _("\
Packit 6c4009
%s: invalid escape `%%%c' sequence in field `%s'"),
Packit 6c4009
				  "LC_ADDRESS", *cp, "postal_fmt");
Packit 6c4009
		    break;
Packit 6c4009
		  }
Packit 6c4009
	      }
Packit 6c4009
	    ++cp;
Packit 6c4009
	  }
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
#define TEST_ELEM(cat) \
Packit 6c4009
  if (address->cat == NULL)						      \
Packit 6c4009
    {									      \
Packit 6c4009
      if (verbose && ! nothing)						      \
Packit 6c4009
	record_warning (_("%s: field `%s' not defined"), "LC_ADDRESS", #cat); \
Packit 6c4009
      address->cat = "";						      \
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  TEST_ELEM (country_name);
Packit 6c4009
  /* XXX Test against list of defined codes.  */
Packit 6c4009
  TEST_ELEM (country_post);
Packit 6c4009
  /* XXX Test against list of defined codes.  */
Packit 6c4009
  TEST_ELEM (country_car);
Packit 6c4009
  /* XXX Test against list of defined codes.  */
Packit 6c4009
  TEST_ELEM (country_isbn);
Packit 6c4009
  TEST_ELEM (lang_name);
Packit 6c4009
Packit 6c4009
  helper = 1;
Packit 6c4009
  if (address->lang_term == NULL)
Packit 6c4009
    {
Packit 6c4009
      if (verbose && ! nothing)
Packit 6c4009
	record_warning (_("%s: field `%s' not defined"), "LC_ADDRESS",
Packit 6c4009
			"lang_term");
Packit 6c4009
      address->lang_term = "";
Packit 6c4009
      cnt = sizeof (iso639) / sizeof (iso639[0]);
Packit 6c4009
    }
Packit 6c4009
  else if (address->lang_term[0] == '\0')
Packit 6c4009
    {
Packit 6c4009
      if (verbose)
Packit 6c4009
	record_warning (_("%s: field `%s' must not be empty"), "LC_ADDRESS",
Packit 6c4009
			"lang_term");
Packit 6c4009
      cnt = sizeof (iso639) / sizeof (iso639[0]);
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      /* Look for this language in the table.  */
Packit 6c4009
      for (cnt = 0; cnt < sizeof (iso639) / sizeof (iso639[0]); ++cnt)
Packit 6c4009
	if (strcmp (address->lang_term, iso639[cnt].term) == 0)
Packit 6c4009
	  break;
Packit 6c4009
      if (cnt == sizeof (iso639) / sizeof (iso639[0]))
Packit 6c4009
	record_error (0, 0, _("\
Packit 6c4009
%s: terminology language code `%s' not defined"),
Packit 6c4009
		      "LC_ADDRESS", address->lang_term);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  if (address->lang_ab == NULL)
Packit 6c4009
    {
Packit 6c4009
      if ((cnt == sizeof (iso639) / sizeof (iso639[0])
Packit 6c4009
	   || iso639[cnt].ab[0] != '\0')
Packit 6c4009
	  && verbose && ! nothing)
Packit 6c4009
	record_warning (_("%s: field `%s' not defined"), "LC_ADDRESS",
Packit 6c4009
			"lang_ab");
Packit 6c4009
      address->lang_ab = "";
Packit 6c4009
    }
Packit 6c4009
  else if (address->lang_ab[0] == '\0')
Packit 6c4009
    {
Packit 6c4009
      if ((cnt == sizeof (iso639) / sizeof (iso639[0])
Packit 6c4009
	   || iso639[cnt].ab[0] != '\0')
Packit 6c4009
	  && verbose)
Packit 6c4009
	record_warning (_("%s: field `%s' must not be empty"),
Packit 6c4009
			"LC_ADDRESS", "lang_ab");
Packit 6c4009
    }
Packit 6c4009
  else if (cnt < sizeof (iso639) / sizeof (iso639[0])
Packit 6c4009
	   && iso639[cnt].ab[0] == '\0')
Packit 6c4009
    {
Packit 6c4009
      record_error (0, 0, _("%s: field `%s' must not be defined"),
Packit 6c4009
		    "LC_ADDRESS", "lang_ab");
Packit 6c4009
Packit 6c4009
      address->lang_ab = "";
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      if (cnt == sizeof (iso639) / sizeof (iso639[0]))
Packit 6c4009
	{
Packit 6c4009
	  helper = 2;
Packit 6c4009
	  for (cnt = 0; cnt < sizeof (iso639) / sizeof (iso639[0]); ++cnt)
Packit 6c4009
	    if (strcmp (address->lang_ab, iso639[cnt].ab) == 0)
Packit 6c4009
	      break;
Packit 6c4009
	  if (cnt == sizeof (iso639) / sizeof (iso639[0]))
Packit 6c4009
	    record_error (0, 0, _("\
Packit 6c4009
%s: language abbreviation `%s' not defined"),
Packit 6c4009
			  "LC_ADDRESS", address->lang_ab);
Packit 6c4009
	}
Packit 6c4009
      else
Packit 6c4009
	if (strcmp (iso639[cnt].ab, address->lang_ab) != 0
Packit 6c4009
	    && iso639[cnt].ab[0] != '\0')
Packit 6c4009
	  record_error (0, 0, _("\
Packit 6c4009
%s: `%s' value does not match `%s' value"),
Packit 6c4009
			"LC_ADDRESS", "lang_ab", "lang_term");
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  if (address->lang_lib == NULL)
Packit 6c4009
    /* This is no error.  */
Packit 6c4009
    address->lang_lib = address->lang_term;
Packit 6c4009
  else if (address->lang_lib[0] == '\0')
Packit 6c4009
    {
Packit 6c4009
      if (verbose)
Packit 6c4009
	record_warning (_("%s: field `%s' must not be empty"),
Packit 6c4009
			"LC_ADDRESS", "lang_lib");
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      if (cnt == sizeof (iso639) / sizeof (iso639[0]))
Packit 6c4009
	{
Packit 6c4009
	  for (cnt = 0; cnt < sizeof (iso639) / sizeof (iso639[0]); ++cnt)
Packit 6c4009
	    if (strcmp (address->lang_lib, iso639[cnt].lib) == 0)
Packit 6c4009
	      break;
Packit 6c4009
	  if (cnt == sizeof (iso639) / sizeof (iso639[0]))
Packit 6c4009
	    record_error (0, 0, _("\
Packit 6c4009
%s: language abbreviation `%s' not defined"),
Packit 6c4009
			  "LC_ADDRESS", address->lang_lib);
Packit 6c4009
	}
Packit 6c4009
      else
Packit 6c4009
	if (strcmp (iso639[cnt].ab, address->lang_ab) != 0)
Packit 6c4009
	  record_error (0, 0, _("\
Packit 6c4009
%s: `%s' value does not match `%s' value"), "LC_ADDRESS", "lang_lib",
Packit 6c4009
			helper == 1 ? "lang_term" : "lang_ab");
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  if (address->country_num == 0)
Packit 6c4009
    {
Packit 6c4009
      if (verbose && ! nothing)
Packit 6c4009
	record_warning (_("%s: field `%s' not defined"), "LC_ADDRESS",
Packit 6c4009
			"country_num");
Packit 6c4009
      cnt = sizeof (iso3166) / sizeof (iso3166[0]);
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      for (cnt = 0; cnt < sizeof (iso3166) / sizeof (iso3166[0]); ++cnt)
Packit 6c4009
	if (address->country_num == iso3166[cnt].num)
Packit 6c4009
	  break;
Packit 6c4009
Packit 6c4009
      if (cnt == sizeof (iso3166) / sizeof (iso3166[0]))
Packit 6c4009
	record_error (0, 0, _("\
Packit 6c4009
%s: numeric country code `%d' not valid"),
Packit 6c4009
		      "LC_ADDRESS", address->country_num);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  if (address->country_ab2 == NULL)
Packit 6c4009
    {
Packit 6c4009
      if (verbose && ! nothing)
Packit 6c4009
	record_warning (_("%s: field `%s' not defined"), "LC_ADDRESS",
Packit 6c4009
			"country_ab2");
Packit 6c4009
      address->country_ab2 = "  ";
Packit 6c4009
    }
Packit 6c4009
  else if (cnt != sizeof (iso3166) / sizeof (iso3166[0])
Packit 6c4009
	   && strcmp (address->country_ab2, iso3166[cnt].ab2) != 0)
Packit 6c4009
    record_error (0, 0, _("%s: `%s' value does not match `%s' value"),
Packit 6c4009
		  "LC_ADDRESS", "country_ab2", "country_num");
Packit 6c4009
Packit 6c4009
  if (address->country_ab3 == NULL)
Packit 6c4009
    {
Packit 6c4009
      if (verbose && ! nothing)
Packit 6c4009
	record_warning (_("%s: field `%s' not defined"), "LC_ADDRESS",
Packit 6c4009
			"country_ab3");
Packit 6c4009
      address->country_ab3 = "   ";
Packit 6c4009
    }
Packit 6c4009
  else if (cnt != sizeof (iso3166) / sizeof (iso3166[0])
Packit 6c4009
	   && strcmp (address->country_ab3, iso3166[cnt].ab3) != 0)
Packit 6c4009
    record_error (0, 0, _("\
Packit 6c4009
%s: `%s' value does not match `%s' value"),
Packit 6c4009
		  "LC_ADDRESS", "country_ab3", "country_num");
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
address_output (struct localedef_t *locale, const struct charmap_t *charmap,
Packit 6c4009
		const char *output_path)
Packit 6c4009
{
Packit 6c4009
  struct locale_address_t *address = locale->categories[LC_ADDRESS].address;
Packit 6c4009
  struct locale_file file;
Packit 6c4009
Packit 6c4009
  init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_ADDRESS));
Packit 6c4009
  add_locale_string (&file, address->postal_fmt);
Packit 6c4009
  add_locale_string (&file, address->country_name);
Packit 6c4009
  add_locale_string (&file, address->country_post);
Packit 6c4009
  add_locale_string (&file, address->country_ab2);
Packit 6c4009
  add_locale_string (&file, address->country_ab3);
Packit 6c4009
  add_locale_string (&file, address->country_car);
Packit 6c4009
  add_locale_uint32 (&file, address->country_num);
Packit 6c4009
  add_locale_string (&file, address->country_isbn);
Packit 6c4009
  add_locale_string (&file, address->lang_name);
Packit 6c4009
  add_locale_string (&file, address->lang_ab);
Packit 6c4009
  add_locale_string (&file, address->lang_term);
Packit 6c4009
  add_locale_string (&file, address->lang_lib);
Packit 6c4009
  add_locale_string (&file, charmap->code_set_name);
Packit 6c4009
  write_locale_data (output_path, LC_ADDRESS, "LC_ADDRESS", &file;;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* The parser for the LC_ADDRESS section of the locale definition.  */
Packit 6c4009
void
Packit 6c4009
address_read (struct linereader *ldfile, struct localedef_t *result,
Packit 6c4009
	      const struct charmap_t *charmap, const char *repertoire_name,
Packit 6c4009
	      int ignore_content)
Packit 6c4009
{
Packit 6c4009
  struct locale_address_t *address;
Packit 6c4009
  struct token *now;
Packit 6c4009
  struct token *arg;
Packit 6c4009
  enum token_t nowtok;
Packit 6c4009
Packit 6c4009
  /* The rest of the line containing `LC_ADDRESS' must be free.  */
Packit 6c4009
  lr_ignore_rest (ldfile, 1);
Packit 6c4009
Packit 6c4009
Packit 6c4009
  do
Packit 6c4009
    {
Packit 6c4009
      now = lr_token (ldfile, charmap, result, NULL, verbose);
Packit 6c4009
      nowtok = now->tok;
Packit 6c4009
    }
Packit 6c4009
  while (nowtok == tok_eol);
Packit 6c4009
Packit 6c4009
  /* If we see `copy' now we are almost done.  */
Packit 6c4009
  if (nowtok == tok_copy)
Packit 6c4009
    {
Packit 6c4009
      handle_copy (ldfile, charmap, repertoire_name, result, tok_lc_address,
Packit 6c4009
		   LC_ADDRESS, "LC_ADDRESS", ignore_content);
Packit 6c4009
      return;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Prepare the data structures.  */
Packit 6c4009
  address_startup (ldfile, result, ignore_content);
Packit 6c4009
  address = result->categories[LC_ADDRESS].address;
Packit 6c4009
Packit 6c4009
  while (1)
Packit 6c4009
    {
Packit 6c4009
      /* Of course we don't proceed beyond the end of file.  */
Packit 6c4009
      if (nowtok == tok_eof)
Packit 6c4009
	break;
Packit 6c4009
Packit 6c4009
      /* Ignore empty lines.  */
Packit 6c4009
      if (nowtok == tok_eol)
Packit 6c4009
	{
Packit 6c4009
	  now = lr_token (ldfile, charmap, result, NULL, verbose);
Packit 6c4009
	  nowtok = now->tok;
Packit 6c4009
	  continue;
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
      switch (nowtok)
Packit 6c4009
	{
Packit 6c4009
#define STR_ELEM(cat) \
Packit 6c4009
	case tok_##cat:							      \
Packit 6c4009
	  /* Ignore the rest of the line if we don't need the input of	      \
Packit 6c4009
	     this line.  */						      \
Packit 6c4009
	  if (ignore_content)						      \
Packit 6c4009
	    {								      \
Packit 6c4009
	      lr_ignore_rest (ldfile, 0);				      \
Packit 6c4009
	      break;							      \
Packit 6c4009
	    }								      \
Packit 6c4009
									      \
Packit 6c4009
	  arg = lr_token (ldfile, charmap, result, NULL, verbose);	      \
Packit 6c4009
	  if (arg->tok != tok_string)					      \
Packit 6c4009
	    goto err_label;						      \
Packit 6c4009
	  if (address->cat != NULL)					      \
Packit 6c4009
	    lr_error (ldfile, _("\
Packit 6c4009
%s: field `%s' declared more than once"), "LC_ADDRESS", #cat);		      \
Packit 6c4009
	  else if (!ignore_content && arg->val.str.startmb == NULL)	      \
Packit 6c4009
	    {								      \
Packit 6c4009
	      lr_error (ldfile, _("\
Packit 6c4009
%s: unknown character in field `%s'"), "LC_ADDRESS", #cat);		      \
Packit 6c4009
	      address->cat = "";					      \
Packit 6c4009
	    }								      \
Packit 6c4009
	  else if (!ignore_content)					      \
Packit 6c4009
	    address->cat = arg->val.str.startmb;			      \
Packit 6c4009
	  break
Packit 6c4009
Packit 6c4009
	  STR_ELEM (postal_fmt);
Packit 6c4009
	  STR_ELEM (country_name);
Packit 6c4009
	  STR_ELEM (country_post);
Packit 6c4009
	  STR_ELEM (country_ab2);
Packit 6c4009
	  STR_ELEM (country_ab3);
Packit 6c4009
	  STR_ELEM (country_car);
Packit 6c4009
	  STR_ELEM (lang_name);
Packit 6c4009
	  STR_ELEM (lang_ab);
Packit 6c4009
	  STR_ELEM (lang_term);
Packit 6c4009
	  STR_ELEM (lang_lib);
Packit 6c4009
Packit 6c4009
#define INT_STR_ELEM(cat) \
Packit 6c4009
	case tok_##cat:							      \
Packit 6c4009
	  /* Ignore the rest of the line if we don't need the input of	      \
Packit 6c4009
	     this line.  */						      \
Packit 6c4009
	  if (ignore_content)						      \
Packit 6c4009
	    {								      \
Packit 6c4009
	      lr_ignore_rest (ldfile, 0);				      \
Packit 6c4009
	      break;							      \
Packit 6c4009
	    }								      \
Packit 6c4009
									      \
Packit 6c4009
	  arg = lr_token (ldfile, charmap, result, NULL, verbose);	      \
Packit 6c4009
	  if (arg->tok != tok_string && arg->tok != tok_number)		      \
Packit 6c4009
	    goto err_label;						      \
Packit 6c4009
	  if (address->cat != NULL)					      \
Packit 6c4009
	    lr_error (ldfile, _("\
Packit 6c4009
%s: field `%s' declared more than once"), "LC_ADDRESS", #cat);		      \
Packit 6c4009
	  else if (!ignore_content && arg->tok == tok_string		      \
Packit 6c4009
		   && arg->val.str.startmb == NULL)			      \
Packit 6c4009
	    {								      \
Packit 6c4009
	      lr_error (ldfile, _("\
Packit 6c4009
%s: unknown character in field `%s'"), "LC_ADDRESS", #cat);		      \
Packit 6c4009
	      address->cat = "";					      \
Packit 6c4009
	    }								      \
Packit 6c4009
	  else if (!ignore_content)					      \
Packit 6c4009
	    {								      \
Packit 6c4009
	      if (arg->tok == tok_string)				      \
Packit 6c4009
		address->cat = arg->val.str.startmb;			      \
Packit 6c4009
	      else							      \
Packit 6c4009
		{							      \
Packit 6c4009
		  char *numbuf = (char *) xmalloc (21);			      \
Packit 6c4009
		  snprintf (numbuf, 21, "%ld", arg->val.num);		      \
Packit 6c4009
		  address->cat = numbuf;				      \
Packit 6c4009
		}							      \
Packit 6c4009
	    }								      \
Packit 6c4009
	  break
Packit 6c4009
Packit 6c4009
	  INT_STR_ELEM (country_isbn);
Packit 6c4009
Packit 6c4009
#define INT_ELEM(cat) \
Packit 6c4009
	case tok_##cat:							      \
Packit 6c4009
	  /* Ignore the rest of the line if we don't need the input of	      \
Packit 6c4009
	     this line.  */						      \
Packit 6c4009
	  if (ignore_content)						      \
Packit 6c4009
	    {								      \
Packit 6c4009
	      lr_ignore_rest (ldfile, 0);				      \
Packit 6c4009
	      break;							      \
Packit 6c4009
	    }								      \
Packit 6c4009
									      \
Packit 6c4009
	  arg = lr_token (ldfile, charmap, result, NULL, verbose);	      \
Packit 6c4009
	  if (arg->tok != tok_number)					      \
Packit 6c4009
	    goto err_label;						      \
Packit 6c4009
	  else if (address->cat != 0)					      \
Packit 6c4009
	    lr_error (ldfile, _("\
Packit 6c4009
%s: field `%s' declared more than once"), "LC_ADDRESS", #cat);		      \
Packit 6c4009
	  else if (!ignore_content)					      \
Packit 6c4009
	    address->cat = arg->val.num;				      \
Packit 6c4009
	  break
Packit 6c4009
Packit 6c4009
	  INT_ELEM (country_num);
Packit 6c4009
Packit 6c4009
	case tok_end:
Packit 6c4009
	  /* Next we assume `LC_ADDRESS'.  */
Packit 6c4009
	  arg = lr_token (ldfile, charmap, result, NULL, verbose);
Packit 6c4009
	  if (arg->tok == tok_eof)
Packit 6c4009
	    break;
Packit 6c4009
	  if (arg->tok == tok_eol)
Packit 6c4009
	    lr_error (ldfile, _("%s: incomplete `END' line"),
Packit 6c4009
		      "LC_ADDRESS");
Packit 6c4009
	  else if (arg->tok != tok_lc_address)
Packit 6c4009
	    lr_error (ldfile, _("\
Packit 6c4009
%1$s: definition does not end with `END %1$s'"), "LC_ADDRESS");
Packit 6c4009
	  lr_ignore_rest (ldfile, arg->tok == tok_lc_address);
Packit 6c4009
	  return;
Packit 6c4009
Packit 6c4009
	default:
Packit 6c4009
	err_label:
Packit 6c4009
	  SYNTAX_ERROR (_("%s: syntax error"), "LC_ADDRESS");
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
      /* Prepare for the next round.  */
Packit 6c4009
      now = lr_token (ldfile, charmap, result, NULL, verbose);
Packit 6c4009
      nowtok = now->tok;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* When we come here we reached the end of the file.  */
Packit 6c4009
  lr_error (ldfile, _("%s: premature end of file"), "LC_ADDRESS");
Packit 6c4009
}