diff options
author | Ulrich Drepper <drepper@redhat.com> | 2000-01-01 19:35:36 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2000-01-01 19:35:36 +0000 |
commit | a673fbcb1f42cd17f54ddeab03e85716ccf15c51 (patch) | |
tree | d4a6776f358cd9cc9e4fa2b8bea269d3ef683afd /locale/programs/ld-ctype.c | |
parent | ac8295d23b59e34d2f7c5757ea71336eab2c9e6e (diff) |
Update.
2000-01-01 Ulrich Drepper <drepper@cygnus.com>
* locale/programs/ld-ctype.c: Implement rest of transliteration
definition parsing.
* locale/programs/locfile-kw.gperf: New keyword translit_ignore.
* locale/programs/locfile-token.h: Add tok_translit_ignore.
Diffstat (limited to 'locale/programs/ld-ctype.c')
-rw-r--r-- | locale/programs/ld-ctype.c | 197 |
1 files changed, 190 insertions, 7 deletions
diff --git a/locale/programs/ld-ctype.c b/locale/programs/ld-ctype.c index bfaf6c7d09..231df137ea 100644 --- a/locale/programs/ld-ctype.c +++ b/locale/programs/ld-ctype.c @@ -85,11 +85,25 @@ struct translit_t { uint32_t *from; + const char *fname; + size_t lineno; + struct translit_to_t *to; struct translit_t *next; }; +struct translit_ignore_t +{ + uint32_t from; + uint32_t to; + + const char *fname; + size_t lineno; + + struct translit_ignore_t *next; +}; + /* The real definition of the struct for the LC_CTYPE locale. */ struct locale_ctype_t @@ -138,6 +152,11 @@ struct locale_ctype_t const char *translit_copy_locale; const char *translit_copy_repertoire; struct translit_t *translit; + struct translit_ignore_t *translit_ignore; + + uint32_t *default_missing; + const char *default_missing_file; + size_t default_missing_lineno; /* The arrays for the binary representation. */ uint32_t plane_size; @@ -162,7 +181,7 @@ struct locale_ctype_t size_t translit_from_tbl_size; size_t translit_to_tbl_size; - struct obstack mem_pool; + struct obstack mempool; }; @@ -282,7 +301,7 @@ ctype_startup (struct linereader *lr, struct localedef_t *locale, ctype->map256_collection[1][cnt] = cnt; } - obstack_init (&ctype->mem_pool); + obstack_init (&ctype->mempool); } } @@ -1537,7 +1556,7 @@ read_widestring (struct linereader *ldfile, struct token *now, else if (now->tok == tok_bsymbol) { /* Get the value from the repertoire. */ - wstr = xmalloc (2 * sizeof (uint32_t)); + wstr = (uint32_t *) xmalloc (2 * sizeof (uint32_t)); wstr[0] = repertoire_find_value (repertoire, now->val.str.startmb, now->val.str.lenmb); if (wstr[0] == ILLEGAL_CHAR_VALUE) @@ -1548,7 +1567,7 @@ read_widestring (struct linereader *ldfile, struct token *now, } else if (now->tok == tok_ucs4) { - wstr = xmalloc (2 * sizeof (uint32_t)); + wstr = (uint32_t *) xmalloc (2 * sizeof (uint32_t)); wstr[0] = now->val.ucs4; wstr[1] = 0; } @@ -1570,14 +1589,14 @@ read_widestring (struct linereader *ldfile, struct token *now, /* We cannot proceed, we don't know the UCS4 value. */ return NULL; - wstr = xmalloc (2 * sizeof (uint32_t)); + wstr = (uint32_t *) xmalloc (2 * sizeof (uint32_t)); wstr[0] = seq->ucs4; wstr[1] = 0; } else if (now->tok == tok_string) { wstr = now->val.str.startwc; - if (wstr[0] == 0) + if (wstr == NULL || wstr[0] == 0) return NULL; } else @@ -1600,7 +1619,7 @@ read_translit_entry (struct linereader *ldfile, struct locale_ctype_t *ctype, uint32_t *from_wstr = read_widestring (ldfile, now, charmap, repertoire); struct translit_t *result; struct translit_to_t **top; - struct obstack *ob = &ctype->mem_pool; + struct obstack *ob = &ctype->mempool; int first; int ignore; @@ -1611,6 +1630,8 @@ read_translit_entry (struct linereader *ldfile, struct locale_ctype_t *ctype, result = (struct translit_t *) obstack_alloc (ob, sizeof (struct translit_t)); result->from = from_wstr; + result->fname = ldfile->fname; + result->lineno = ldfile->lineno; result->next = NULL; result->to = NULL; top = &result->to; @@ -1673,6 +1694,129 @@ read_translit_entry (struct linereader *ldfile, struct locale_ctype_t *ctype, } +static void +read_translit_ignore_entry (struct linereader *ldfile, + struct locale_ctype_t *ctype, + struct charmap_t *charmap, + struct repertoire_t *repertoire) +{ + /* We expect a semicolon-separated list of characters we ignore. We are + only interested in the wide character definitions. These must be + single characters, possibly defining a range when an ellipsis is used. */ + while (1) + { + struct token *now = lr_token (ldfile, charmap, repertoire); + struct translit_ignore_t *newp; + uint32_t from; + + if (now->tok == tok_eol || now->tok == tok_eof) + { + lr_error (ldfile, + _("premature end of `translit_ignore' definition")); + return; + } + + if (now->tok != tok_bsymbol && now->tok != tok_ucs4) + { + lr_error (ldfile, _("syntax error")); + lr_ignore_rest (ldfile, 0); + return; + } + + if (now->tok == tok_ucs4) + from = now->val.ucs4; + else + { + /* Try to get the value. */ + from = repertoire_find_value (repertoire, now->val.str.startmb, + now->val.str.lenmb); + } + + if (from == ILLEGAL_CHAR_VALUE) + { + lr_error (ldfile, "invalid character name"); + newp = NULL; + } + else + { + newp = (struct translit_ignore_t *) + obstack_alloc (&ctype->mempool, sizeof (struct translit_ignore_t)); + newp->from = from; + newp->to = from; + + newp->next = ctype->translit_ignore; + ctype->translit_ignore = newp; + } + + /* Now we expect either a semicolon, an ellipsis, or the end of the + line. */ + now = lr_token (ldfile, charmap, repertoire); + + if (now->tok == tok_ellipsis2) + { + /* XXX Should we bother implementing `....'? `...' certainly + will not be implemented. */ + uint32_t to; + + now = lr_token (ldfile, charmap, repertoire); + + if (now->tok == tok_eol || now->tok == tok_eof) + { + lr_error (ldfile, + _("premature end of `translit_ignore' definition")); + return; + } + + if (now->tok != tok_bsymbol && now->tok != tok_ucs4) + { + lr_error (ldfile, _("syntax error")); + lr_ignore_rest (ldfile, 0); + return; + } + + if (now->tok == tok_ucs4) + to = now->val.ucs4; + else + { + /* Try to get the value. */ + to = repertoire_find_value (repertoire, now->val.str.startmb, + now->val.str.lenmb); + } + + if (to == ILLEGAL_CHAR_VALUE) + lr_error (ldfile, "invalid character name"); + else + { + /* Make sure the `to'-value is larger. */ + if (to >= from) + newp->to = to; + else + lr_error (ldfile, _("\ +to-value <U%0*X> of range is smaller than from-value <U%0*X>"), + (to | from) < 65536 ? 4 : 8, to, + (to | from) < 65536 ? 4 : 8, from); + } + + /* And the next token. */ + now = lr_token (ldfile, charmap, repertoire); + } + + if (now->tok == tok_eol || now->tok == tok_eof) + /* We are done. */ + return; + + if (now->tok == tok_semicolon) + /* Next round. */ + continue; + + /* If we come here something is wrong. */ + lr_error (ldfile, _("syntax error")); + lr_ignore_rest (ldfile, 0); + return; + } +} + + /* The parser for the LC_CTYPE section of the locale definition. */ void ctype_read (struct linereader *ldfile, struct localedef_t *result, @@ -2257,6 +2401,45 @@ with character code range values one must use the absolute ellipsis `...'")); /* The rest of the line must be empty. */ lr_ignore_rest (ldfile, 1); + + /* Make sure the locale is read. */ + add_to_readlist (LC_CTYPE, ctype->translit_copy_locale, + repertoire_name, 1); + continue; + } + else if (now->tok == tok_default_missing) + { + uint32_t *wstr; + + /* We expect a single character or string as the + argument. */ + now = lr_token (ldfile, charmap, NULL); + wstr = read_widestring (ldfile, now, charmap, repertoire); + + if (wstr != NULL) + { + if (ctype->default_missing != NULL) + { + lr_error (ldfile, _("\ +%s: duplicate `default_missing' definition"), "LC_CTYPE"); + error_at_line (0, 0, ctype->default_missing_file, + ctype->default_missing_lineno, + _("previous definition was here")); + } + else + { + ctype->default_missing = wstr; + ctype->default_missing_file = ldfile->fname; + ctype->default_missing_lineno = ldfile->lineno; + } + } + lr_ignore_rest (ldfile, 1); + continue; + } + else if (now->tok == tok_translit_ignore) + { + read_translit_ignore_entry (ldfile, ctype, charmap, + repertoire); continue; } |