-/* Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.org>, 1996.
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; version 2 of the License, or
+ (at your option) any later version.
- The GNU C Library is distributed in the hope that it will be useful,
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
+#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <libintl.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
+#include <stdint.h>
+#include "localedef.h"
#include "charmap.h"
#include "error.h"
#include "linereader.h"
-#include "localedef.h"
-
+#include "locfile.h"
/* Prototypes for local functions. */
static struct token *get_toplvl_escape (struct linereader *lr);
static struct token *get_ident (struct linereader *lr);
static struct token *get_string (struct linereader *lr,
const struct charmap_t *charmap,
- const struct repertoire_t *repertoire);
+ struct localedef_t *locale,
+ const struct repertoire_t *repertoire,
+ int verbose);
struct linereader *
lr_open (const char *fname, kw_hash_fct_t hf)
{
FILE *fp;
- struct linereader *result;
- int n;
if (fname == NULL || strcmp (fname, "-") == 0
|| strcmp (fname, "/dev/stdin") == 0)
- fp = stdin;
+ return lr_create (stdin, "<stdin>", hf);
else
{
- fp = fopen (fname, "r");
+ fp = fopen (fname, "rm");
if (fp == NULL)
return NULL;
+ return lr_create (fp, fname, hf);
}
+}
+
+struct linereader *
+lr_create (FILE *fp, const char *fname, kw_hash_fct_t hf)
+{
+ struct linereader *result;
+ int n;
result = (struct linereader *) xmalloc (sizeof (*result));
result->fp = fp;
- result->fname = xstrdup (fname ? : "<stdin>");
+ result->fname = xstrdup (fname);
result->buf = NULL;
result->bufsize = 0;
result->lineno = 1;
result->comment_char = '#';
result->escape_char = '\\';
result->translate_strings = 1;
+ result->return_widestr = 0;
n = getdelim (&result->buf, &result->bufsize, '\n', result->fp);
if (n < 0)
}
+void
+lr_ignore_rest (struct linereader *lr, int verbose)
+{
+ if (verbose)
+ {
+ while (isspace (lr->buf[lr->idx]) && lr->buf[lr->idx] != '\n'
+ && lr->buf[lr->idx] != lr->comment_char)
+ if (lr->buf[lr->idx] == '\0')
+ {
+ if (lr_next (lr) < 0)
+ return;
+ }
+ else
+ ++lr->idx;
+
+ if (lr->buf[lr->idx] != '\n' && ! feof (lr->fp)
+ && lr->buf[lr->idx] != lr->comment_char)
+ lr_error (lr, _("trailing garbage at end of line"));
+ }
+
+ /* Ignore continued line. */
+ while (lr->bufact > 0 && lr->buf[lr->bufact - 1] != '\n')
+ if (lr_next (lr) < 0)
+ break;
+
+ lr->idx = lr->bufact;
+}
+
+
void
lr_close (struct linereader *lr)
{
struct token *
lr_token (struct linereader *lr, const struct charmap_t *charmap,
- const struct repertoire_t *repertoire)
+ struct localedef_t *locale, const struct repertoire_t *repertoire,
+ int verbose)
{
int ch;
}
while (isspace (ch));
- if (ch == EOF)
- {
- lr->token.tok = tok_eof;
- return &lr->token;
- };
-
if (ch != lr->comment_char)
break;
return &lr->token;
case '"':
- return get_string (lr, charmap, repertoire);
+ return get_string (lr, charmap, locale, repertoire, verbose);
case '-':
ch = lr_getc (lr);
/* This is supposed to be a numeric value. We return the
numerical value and the number of bytes. */
size_t start_idx = lr->idx - 1;
- char *bytes = lr->token.val.charcode.bytes;
- int nbytes = 0;
+ unsigned char *bytes = lr->token.val.charcode.bytes;
+ size_t nbytes = 0;
int ch;
do
bytes[nbytes++] = byte;
}
- while (ch == lr->escape_char && nbytes < 4);
+ while (ch == lr->escape_char
+ && nbytes < (int) sizeof (lr->token.val.charcode.bytes));
if (!isspace (ch))
lr_error (lr, _("garbage at end of character code specification"));
{
lr->token.tok = tok_bsymbol;
- buf[bufact] = '\0';
buf = xrealloc (buf, bufact + 1);
+ buf[bufact] = '\0';
lr->token.val.str.startmb = buf;
lr->token.val.str.lenmb = bufact - 1;
ADDC (lr->buf[lr->idx - 1]);
while (!isspace ((ch = lr_getc (lr))) && ch != '"' && ch != ';'
- && ch != '<' && ch != ',')
+ && ch != '<' && ch != ',' && ch != EOF)
{
if (ch == lr->escape_char)
{
ADDC (ch);
}
- lr_ungetn (lr, 1);
+ lr_ungetc (lr, ch);
kw = lr->hash_fct (buf, bufact);
{
lr->token.tok = tok_ident;
- buf[bufact] = '\0';
buf = xrealloc (buf, bufact + 1);
+ buf[bufact] = '\0';
lr->token.val.str.startmb = buf;
lr->token.val.str.lenmb = bufact;
static struct token *
get_string (struct linereader *lr, const struct charmap_t *charmap,
- const struct repertoire_t *repertoire)
+ struct localedef_t *locale, const struct repertoire_t *repertoire,
+ int verbose)
{
int return_widestr = lr->return_widestr;
char *buf;
if (cp == &buf[bufact])
{
char utmp[10];
- const char *symbol = NULL;
/* Yes, it is. */
ADDC ('\0');
the repertoire the name of the character and
find it in the charmap. */
if (repertoire != NULL)
- symbol = repertoire_find_symbol (repertoire, wch);
-
- if (symbol == NULL)
- /* We cannot generate a string since we
- cannot map from the Unicode number to the
- character symbol. */
- illegal_string = 1;
- else
{
- seq = charmap_find_value (charmap, symbol,
- strlen (symbol));
+ const char *symbol;
- if (seq == NULL)
- /* Not a known name. */
- illegal_string = 1;
+ symbol = repertoire_find_symbol (repertoire, wch);
+
+ if (symbol != NULL)
+ seq = charmap_find_value (charmap, symbol,
+ strlen (symbol));
+ }
+
+ if (seq == NULL)
+ {
+#ifndef NO_TRANSLITERATION
+ /* Transliterate if possible. */
+ if (locale != NULL)
+ {
+ uint32_t *translit;
+
+ if ((locale->avail & CTYPE_LOCALE) == 0)
+ {
+ /* Load the CTYPE data now. */
+ int old_needed = locale->needed;
+
+ locale->needed = 0;
+ locale = load_locale (LC_CTYPE,
+ locale->name,
+ locale->repertoire_name,
+ charmap, locale);
+ locale->needed = old_needed;
+ }
+
+ if ((locale->avail & CTYPE_LOCALE) != 0
+ && ((translit = find_translit (locale,
+ charmap, wch))
+ != NULL))
+ /* The CTYPE data contains a matching
+ transliteration. */
+ {
+ int i;
+
+ for (i = 0; translit[i] != 0; ++i)
+ {
+ char utmp[10];
+
+ snprintf (utmp, sizeof (utmp), "U%08X",
+ translit[i]);
+ seq = charmap_find_value (charmap, utmp,
+ 9);
+ assert (seq != NULL);
+ ADDS (seq->bytes, seq->nbytes);
+ }
+
+ continue;
+ }
+ }
+#endif /* NO_TRANSLITERATION */
+
+ /* Not a known name. */
+ illegal_string = 1;
}
}
if (illegal_string)
{
free (buf);
- if (buf2 != NULL)
- free (buf2);
+ free (buf2);
lr->token.val.str.startmb = NULL;
lr->token.val.str.lenmb = 0;
+ lr->token.val.str.startwc = NULL;
+ lr->token.val.str.lenwc = 0;
return &lr->token;
}