Example #1
0
struct token *
lr_token (struct linereader *lr, const struct charmap_t *charmap,
	  struct localedef_t *locale, const struct repertoire_t *repertoire,
	  int verbose)
{
  int ch;

  while (1)
    {
      do
	{
	  ch = lr_getc (lr);

	  if (ch == EOF)
	    {
	      lr->token.tok = tok_eof;
	      return &lr->token;
	    };

	  if (ch == '\n')
	    {
	      lr->token.tok = tok_eol;
	      return &lr->token;
	    }
	}
      while (isspace (ch));

      if (ch != lr->comment_char)
	break;

      /* Is there an newline at the end of the buffer?  */
      if (lr->buf[lr->bufact - 1] != '\n')
	{
	  /* No.  Some people want this to mean that only the line in
	     the file not the logical, concatenated line is ignored.
	     Let's try this.  */
	  lr->idx = lr->bufact;
	  continue;
	}

      /* Ignore rest of line.  */
      lr_ignore_rest (lr, 0);
      lr->token.tok = tok_eol;
      return &lr->token;
    }

  /* Match escape sequences.  */
  if (ch == lr->escape_char)
    return get_toplvl_escape (lr);

  /* Match ellipsis.  */
  if (ch == '.')
    {
      if (strncmp (&lr->buf[lr->idx], "...(2)....", 10) == 0)
	{
	  int cnt;
	  for (cnt = 0; cnt < 10; ++cnt)
	    lr_getc (lr);
	  lr->token.tok = tok_ellipsis4_2;
	  return &lr->token;
	}
      if (strncmp (&lr->buf[lr->idx], "...", 3) == 0)
	{
	  lr_getc (lr);
	  lr_getc (lr);
	  lr_getc (lr);
	  lr->token.tok = tok_ellipsis4;
	  return &lr->token;
	}
      if (strncmp (&lr->buf[lr->idx], "..", 2) == 0)
	{
	  lr_getc (lr);
	  lr_getc (lr);
	  lr->token.tok = tok_ellipsis3;
	  return &lr->token;
	}
      if (strncmp (&lr->buf[lr->idx], ".(2)..", 6) == 0)
	{
	  int cnt;
	  for (cnt = 0; cnt < 6; ++cnt)
	    lr_getc (lr);
	  lr->token.tok = tok_ellipsis2_2;
	  return &lr->token;
	}
      if (lr->buf[lr->idx] == '.')
	{
	  lr_getc (lr);
	  lr->token.tok = tok_ellipsis2;
	  return &lr->token;
	}
    }

  switch (ch)
    {
    case '<':
      return get_symname (lr);

    case '0' ... '9':
      lr->token.tok = tok_number;
      lr->token.val.num = ch - '0';

      while (isdigit (ch = lr_getc (lr)))
	{
	  lr->token.val.num *= 10;
	  lr->token.val.num += ch - '0';
	}
      if (isalpha (ch))
	lr_error (lr, _("garbage at end of number"));
      lr_ungetn (lr, 1);

      return &lr->token;

    case ';':
      lr->token.tok = tok_semicolon;
      return &lr->token;

    case ',':
      lr->token.tok = tok_comma;
      return &lr->token;

    case '(':
      lr->token.tok = tok_open_brace;
      return &lr->token;

    case ')':
      lr->token.tok = tok_close_brace;
      return &lr->token;

    case '"':
      return get_string (lr, charmap, locale, repertoire, verbose);

    case '-':
      ch = lr_getc (lr);
      if (ch == '1')
	{
	  lr->token.tok = tok_minus1;
	  return &lr->token;
	}
      lr_ungetn (lr, 2);
      break;
    }

  return get_ident (lr);
}
Example #2
0
int
locfile_read (struct localedef_t *result, const struct charmap_t *charmap)
{
    const char *filename = result->name;
    const char *repertoire_name = result->repertoire_name;
    int locale_mask = result->needed & ~result->avail;
    struct linereader *ldfile;
    int not_here = ALL_LOCALES;

    /* If no repertoire name was specified use the global one.  */
    if (repertoire_name == NULL)
        repertoire_name = repertoire_global;

    /* Open the locale definition file.  */
    ldfile = lr_open (filename, locfile_hash);
    if (ldfile == NULL)
    {
        if (filename != NULL && filename[0] != '/')
        {
            char *i18npath = getenv ("I18NPATH");
            if (i18npath != NULL && *i18npath != '\0')
            {
                const size_t pathlen = strlen (i18npath);
                char i18npathbuf[pathlen + 1];
                char path[strlen (filename) + 1 + pathlen
                          + sizeof ("/locales/") - 1];
                char *next;
                i18npath = memcpy (i18npathbuf, i18npath, pathlen + 1);

                while (ldfile == NULL
                        && (next = strsep (&i18npath, ":")) != NULL)
                {
                    stpcpy (stpcpy (stpcpy (path, next), "/locales/"), filename);

                    ldfile = lr_open (path, locfile_hash);

                    if (ldfile == NULL)
                    {
                        stpcpy (stpcpy (path, next), filename);

                        ldfile = lr_open (path, locfile_hash);
                    }
                }
            }

            /* Test in the default directory.  */
            if (ldfile == NULL)
            {
                char path[strlen (filename) + 1 + sizeof (LOCSRCDIR)];

                stpcpy (stpcpy (stpcpy (path, LOCSRCDIR), "/"), filename);
                ldfile = lr_open (path, locfile_hash);
            }
        }

        if (ldfile == NULL)
            return 1;
    }

    /* Parse locale definition file and store result in RESULT.  */
    while (1)
    {
        struct token *now = lr_token (ldfile, charmap, NULL, NULL, verbose);
        enum token_t nowtok = now->tok;
        struct token *arg;

        if (nowtok == tok_eof)
            break;

        if (nowtok == tok_eol)
            /* Ignore empty lines.  */
            continue;

        switch (nowtok)
        {
        case tok_escape_char:
        case tok_comment_char:
            /* We need an argument.  */
            arg = lr_token (ldfile, charmap, NULL, NULL, verbose);

            if (arg->tok != tok_ident)
            {
                SYNTAX_ERROR (_("bad argument"));
                continue;
            }

            if (arg->val.str.lenmb != 1)
            {
                lr_error (ldfile, _("\
argument to `%s' must be a single character"),
                          nowtok == tok_escape_char
                          ? "escape_char" : "comment_char");

                lr_ignore_rest (ldfile, 0);
                continue;
            }

            if (nowtok == tok_escape_char)
                ldfile->escape_char = *arg->val.str.startmb;
            else
                ldfile->comment_char = *arg->val.str.startmb;
            break;

        case tok_repertoiremap:
            /* We need an argument.  */
            arg = lr_token (ldfile, charmap, NULL, NULL, verbose);

            if (arg->tok != tok_ident)
            {
                SYNTAX_ERROR (_("bad argument"));
                continue;
            }

            if (repertoire_name == NULL)
            {
                char *newp = alloca (arg->val.str.lenmb + 1);

                *((char *) mempcpy (newp, arg->val.str.startmb,
                                    arg->val.str.lenmb)) = '\0';
                repertoire_name = newp;
            }
            break;

        case tok_lc_ctype:
            ctype_read (ldfile, result, charmap, repertoire_name,
                        (locale_mask & CTYPE_LOCALE) == 0);
            result->avail |= locale_mask & CTYPE_LOCALE;
            not_here ^= CTYPE_LOCALE;
            continue;

        case tok_lc_collate:
            collate_read (ldfile, result, charmap, repertoire_name,
                          (locale_mask & COLLATE_LOCALE) == 0);
            result->avail |= locale_mask & COLLATE_LOCALE;
            not_here ^= COLLATE_LOCALE;
            continue;

        case tok_lc_monetary:
            monetary_read (ldfile, result, charmap, repertoire_name,
                           (locale_mask & MONETARY_LOCALE) == 0);
            result->avail |= locale_mask & MONETARY_LOCALE;
            not_here ^= MONETARY_LOCALE;
            continue;

        case tok_lc_numeric:
            numeric_read (ldfile, result, charmap, repertoire_name,
                          (locale_mask & NUMERIC_LOCALE) == 0);
            result->avail |= locale_mask & NUMERIC_LOCALE;
            not_here ^= NUMERIC_LOCALE;
            continue;

        case tok_lc_time:
            time_read (ldfile, result, charmap, repertoire_name,
                       (locale_mask & TIME_LOCALE) == 0);
            result->avail |= locale_mask & TIME_LOCALE;
            not_here ^= TIME_LOCALE;
            continue;

        case tok_lc_messages:
            messages_read (ldfile, result, charmap, repertoire_name,
                           (locale_mask & MESSAGES_LOCALE) == 0);
            result->avail |= locale_mask & MESSAGES_LOCALE;
            not_here ^= MESSAGES_LOCALE;
            continue;

        case tok_lc_paper:
            paper_read (ldfile, result, charmap, repertoire_name,
                        (locale_mask & PAPER_LOCALE) == 0);
            result->avail |= locale_mask & PAPER_LOCALE;
            not_here ^= PAPER_LOCALE;
            continue;

        case tok_lc_name:
            name_read (ldfile, result, charmap, repertoire_name,
                       (locale_mask & NAME_LOCALE) == 0);
            result->avail |= locale_mask & NAME_LOCALE;
            not_here ^= NAME_LOCALE;
            continue;

        case tok_lc_address:
            address_read (ldfile, result, charmap, repertoire_name,
                          (locale_mask & ADDRESS_LOCALE) == 0);
            result->avail |= locale_mask & ADDRESS_LOCALE;
            not_here ^= ADDRESS_LOCALE;
            continue;

        case tok_lc_telephone:
            telephone_read (ldfile, result, charmap, repertoire_name,
                            (locale_mask & TELEPHONE_LOCALE) == 0);
            result->avail |= locale_mask & TELEPHONE_LOCALE;
            not_here ^= TELEPHONE_LOCALE;
            continue;

        case tok_lc_measurement:
            measurement_read (ldfile, result, charmap, repertoire_name,
                              (locale_mask & MEASUREMENT_LOCALE) == 0);
            result->avail |= locale_mask & MEASUREMENT_LOCALE;
            not_here ^= MEASUREMENT_LOCALE;
            continue;

        case tok_lc_identification:
            identification_read (ldfile, result, charmap, repertoire_name,
                                 (locale_mask & IDENTIFICATION_LOCALE) == 0);
            result->avail |= locale_mask & IDENTIFICATION_LOCALE;
            not_here ^= IDENTIFICATION_LOCALE;
            continue;

        default:
            SYNTAX_ERROR (_("\
syntax error: not inside a locale definition section"));
            continue;
        }

        /* The rest of the line must be empty.  */
        lr_ignore_rest (ldfile, 1);
    }