diff options
author | Bruno Haible <bruno@clisp.org> | 2001-03-08 08:01:01 +0000 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2001-03-08 08:01:01 +0000 |
commit | 7ece9f36becc1cc48ffe69f361c8181eed8a67ad (patch) | |
tree | 1a90d6726eee161437e38a53ecdc0f42eb97ef2b /src | |
parent | 8cfea163b48cd88af87615334b5f6408264c2377 (diff) | |
download | external_gettext-7ece9f36becc1cc48ffe69f361c8181eed8a67ad.zip external_gettext-7ece9f36becc1cc48ffe69f361c8181eed8a67ad.tar.gz external_gettext-7ece9f36becc1cc48ffe69f361c8181eed8a67ad.tar.bz2 |
Check syntax of obsolete entries of PO files, not only in msgmerge.
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 25 | ||||
-rw-r--r-- | src/po-gram-gen.y | 146 | ||||
-rw-r--r-- | src/po-lex.c | 74 | ||||
-rw-r--r-- | src/po-lex.h | 4 |
4 files changed, 167 insertions, 82 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index cf4062b..ec4aed3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,28 @@ +2001-03-04 Bruno Haible <haible@clisp.cons.org> + + Check syntax of obsolete entries of PO files, not only in msgmerge. + * po-lex.h (pass_obsolete_entries): New declaration. + (msgstr_def): Remove pos field. + * po-lex.c (po_lex_obsolete): New variable. + (pass_obsolete_entries): Make non-static. + (lex_open): Initialize po_lex_obsolete. + (lex_close): Reset po_lex_obsolete. + (po_gram_lex): Don't look at pass_obsolete_entries. Instead, set + po_lex_obsolete to 1 when "#~" is seen. Reset po_lex_obsolete when + a newline is seen. Before returning, fill the 'pos' and 'obsolete' + fields of any token. + * po-gram.gen.y (check_obsolete): New macro. + (union): Add a 'pos' and 'obsolete' field for any symbol type. + (NAME): Assign to type <string>. + (DOMAIN, MSGID, MSGID_PLURAL, MSGSTR, '[', ']'): Assign to type <pos>. + (msgid, msgstr): Remove. + (message, msgid_pluralform, pluralform_list, pluralform, string_list): + Signal an error if the 'obsolete' field is not the same across the + entire token sequence of the rule. + (message): Deal with pass_obsolete_entries here. + (msgid_pluralform, pluralform_list, pluralform, string_list): Fill the + 'pos' and 'obsolete' fields of $$. + 2001-03-03 Bruno Haible <haible@clisp.cons.org> Fix parsing of strings in CJK encodings. diff --git a/src/po-gram-gen.y b/src/po-gram-gen.y index ddd776d..1b576aa 100644 --- a/src/po-gram-gen.y +++ b/src/po-gram-gen.y @@ -81,6 +81,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define yycheck po_gram_yycheck static long plural_counter; + +#define check_obsolete(value1,value2) \ + if ((value1).obsolete != (value2).obsolete) \ + po_gram_error_at_line (&(value2).pos, _("inconsistent use of #~")); + %} %token COMMENT @@ -96,15 +101,15 @@ static long plural_counter; %union { - char *string; - long number; - lex_pos_ty pos; - struct msgstr_def rhs; + struct { char *string; lex_pos_ty pos; int obsolete; } string; + struct { long number; lex_pos_ty pos; int obsolete; } number; + struct { lex_pos_ty pos; int obsolete; } pos; + struct { struct msgstr_def rhs; lex_pos_ty pos; int obsolete; } rhs; } -%type <string> STRING COMMENT string_list msgid_pluralform +%type <string> STRING COMMENT NAME string_list msgid_pluralform %type <number> NUMBER -%type <pos> msgid msgstr +%type <pos> DOMAIN MSGID MSGID_PLURAL MSGSTR '[' ']' %type <rhs> pluralform pluralform_list %right MSGSTR @@ -122,45 +127,72 @@ msgfmt domain : DOMAIN STRING { - po_callback_domain ($2); + po_callback_domain ($2.string); } ; message - : msgid string_list msgstr string_list + : MSGID string_list MSGSTR string_list { - po_callback_message ($2, &$1, NULL, - $4, strlen ($4) + 1, &$3); + check_obsolete ($1, $2); + check_obsolete ($1, $3); + check_obsolete ($1, $4); + if (!$1.obsolete || pass_obsolete_entries) + po_callback_message ($2.string, &$1.pos, NULL, + $4.string, strlen ($4.string) + 1, &$3.pos); + else + { + free ($2.string); + free ($4.string); + } } - | msgid string_list msgid_pluralform pluralform_list + | MSGID string_list msgid_pluralform pluralform_list { - po_callback_message ($2, &$1, $3, - $4.msgstr, $4.msgstr_len, &$4.pos); + check_obsolete ($1, $2); + check_obsolete ($1, $3); + check_obsolete ($1, $4); + if (!$1.obsolete || pass_obsolete_entries) + po_callback_message ($2.string, &$1.pos, $3.string, + $4.rhs.msgstr, $4.rhs.msgstr_len, &$4.pos); + else + { + free ($2.string); + free ($3.string); + free ($4.rhs.msgstr); + } } - | msgid string_list msgid_pluralform + | MSGID string_list msgid_pluralform { - po_gram_error_at_line (&$1, _("missing `msgstr[]' section")); - free ($2); - free ($3); + check_obsolete ($1, $2); + check_obsolete ($1, $3); + po_gram_error_at_line (&$1.pos, _("missing `msgstr[]' section")); + free ($2.string); + free ($3.string); } - | msgid string_list pluralform_list + | MSGID string_list pluralform_list { - po_gram_error_at_line (&$1, _("missing `msgid_plural' section")); - free ($2); - free ($3.msgstr); + check_obsolete ($1, $2); + check_obsolete ($1, $3); + po_gram_error_at_line (&$1.pos, _("missing `msgid_plural' section")); + free ($2.string); + free ($3.rhs.msgstr); } - | msgid string_list + | MSGID string_list { - po_gram_error_at_line (&$1, _("missing `msgstr' section")); - free ($2); + check_obsolete ($1, $2); + po_gram_error_at_line (&$1.pos, _("missing `msgstr' section")); + free ($2.string); } ; msgid_pluralform : MSGID_PLURAL string_list { + check_obsolete ($1, $2); plural_counter = 0; - $$ = $2; + $$.string = $2.string; + $$.pos = $1.pos; + $$.obsolete = $1.obsolete; } ; @@ -171,44 +203,37 @@ pluralform_list } | pluralform_list pluralform { - $$.msgstr = (char *) xmalloc ($1.msgstr_len + $2.msgstr_len); - memcpy ($$.msgstr, $1.msgstr, $1.msgstr_len); - memcpy ($$.msgstr + $1.msgstr_len, $2.msgstr, $2.msgstr_len); - $$.msgstr_len = $1.msgstr_len + $2.msgstr_len; + check_obsolete ($1, $2); + $$.rhs.msgstr = (char *) xmalloc ($1.rhs.msgstr_len + $2.rhs.msgstr_len); + memcpy ($$.rhs.msgstr, $1.rhs.msgstr, $1.rhs.msgstr_len); + memcpy ($$.rhs.msgstr + $1.rhs.msgstr_len, $2.rhs.msgstr, $2.rhs.msgstr_len); + $$.rhs.msgstr_len = $1.rhs.msgstr_len + $2.rhs.msgstr_len; + free ($1.rhs.msgstr); + free ($2.rhs.msgstr); $$.pos = $1.pos; - free ($1.msgstr); - free ($2.msgstr); + $$.obsolete = $1.obsolete; } ; pluralform - : msgstr '[' NUMBER ']' string_list + : MSGSTR '[' NUMBER ']' string_list { - if ($3 != plural_counter) + check_obsolete ($1, $2); + check_obsolete ($1, $3); + check_obsolete ($1, $4); + check_obsolete ($1, $5); + if ($3.number != plural_counter) { if (plural_counter == 0) - po_gram_error_at_line (&$1, _("first plural form has nonzero index")); + po_gram_error_at_line (&$1.pos, _("first plural form has nonzero index")); else - po_gram_error_at_line (&$1, _("plural form has wrong index")); + po_gram_error_at_line (&$1.pos, _("plural form has wrong index")); } plural_counter++; - $$.msgstr = $5; - $$.msgstr_len = strlen ($5) + 1; - $$.pos = $1; - } - ; - -msgid - : MSGID - { - $$ = gram_pos; - } - ; - -msgstr - : MSGSTR - { - $$ = gram_pos; + $$.rhs.msgstr = $5.string; + $$.rhs.msgstr_len = strlen ($5.string) + 1; + $$.pos = $1.pos; + $$.obsolete = $1.obsolete; } ; @@ -222,18 +247,21 @@ string_list size_t len1; size_t len2; - len1 = strlen ($1); - len2 = strlen ($2); - $$ = (char *) xmalloc (len1 + len2 + 1); - stpcpy (stpcpy ($$, $1), $2); - free ($1); - free ($2); + check_obsolete ($1, $2); + len1 = strlen ($1.string); + len2 = strlen ($2.string); + $$.string = (char *) xmalloc (len1 + len2 + 1); + stpcpy (stpcpy ($$.string, $1.string), $2.string); + free ($1.string); + free ($2.string); + $$.pos = $1.pos; + $$.obsolete = $1.obsolete; } ; comment : COMMENT { - po_callback_comment ($1); + po_callback_comment ($1.string); } ; diff --git a/src/po-lex.c b/src/po-lex.c index cf43fe7..509f802 100644 --- a/src/po-lex.c +++ b/src/po-lex.c @@ -59,12 +59,13 @@ static FILE *fp; lex_pos_ty gram_pos; unsigned int gram_max_allowed_errors = 20; +static int po_lex_obsolete; const char *po_lex_charset; #if HAVE_ICONV iconv_t po_lex_iconv; #endif static int pass_comments = 0; -static int pass_obsolete_entries = 0; +int pass_obsolete_entries = 0; /* Prototypes for local functions. */ @@ -85,6 +86,7 @@ lex_open (fname) _("error while opening \"%s\" for reading"), fname); gram_pos.line_number = 1; + po_lex_obsolete = 0; po_lex_charset = NULL; #if HAVE_ICONV po_lex_iconv = (iconv_t)(-1); @@ -105,6 +107,7 @@ lex_close () gram_pos.file_name = 0; gram_pos.line_number = 0; error_message_count = 0; + po_lex_obsolete = 0; po_lex_charset = NULL; #if HAVE_ICONV if (po_lex_iconv != (iconv_t)(-1)) @@ -374,7 +377,7 @@ control_sequence () /* Return the next token in the PO file. The return codes are defined - in "po-gram-gen2.h". Associated data is put in 'po_gram_lval. */ + in "po-gram-gen2.h". Associated data is put in 'po_gram_lval'. */ int po_gram_lex () { @@ -392,27 +395,32 @@ po_gram_lex () /* Yacc want this for end of file. */ return 0; + case '\n': + po_lex_obsolete = 0; + break; + case ' ': case '\t': - case '\n': case '\r': case '\f': case '\v': break; case '#': + c = lex_getc (); + if (c == '~') + /* A pseudo-comment beginning with #~ is found. This is + not a comment. It is the format for obsolete entries. + We simply discard the "#~" prefix. The following + characters are expected to be well formed. */ + { + po_lex_obsolete = 1; + break; + } + /* Accumulate comments into a buffer. If we have been asked to pass comments, generate a COMMENT token, otherwise discard it. */ - c = lex_getc (); - if (c == '~' && pass_obsolete_entries) - /* A special comment beginning with #~ is found. This - is the format for obsolete entries and if we are - asked to return them is entries not as comments be - simply stop processing the comment here. The - following characters are expected to be well formed. */ - break; - if (pass_comments) { bufpos = 0; @@ -431,15 +439,21 @@ po_gram_lex () } buf[bufpos] = 0; - po_gram_lval.string = buf; + po_gram_lval.string.string = buf; + po_gram_lval.string.pos = gram_pos; + po_gram_lval.string.obsolete = po_lex_obsolete; + po_lex_obsolete = 0; return COMMENT; } else - /* We do this in separate loop because collecting large - comments while they get not passed to the upper layers - is not very effective. */ - while (c != EOF && c != '\n') - c = lex_getc (); + { + /* We do this in separate loop because collecting large + comments while they get not passed to the upper layers + is not very effective. */ + while (c != EOF && c != '\n') + c = lex_getc (); + po_lex_obsolete = 0; + } break; case '"': @@ -519,7 +533,9 @@ po_gram_lex () buf[bufpos] = 0; /* FIXME: Treatment of embedded \000 chars is incorrect. */ - po_gram_lval.string = xstrdup (buf); + po_gram_lval.string.string = xstrdup (buf); + po_gram_lval.string.pos = gram_pos; + po_gram_lval.string.obsolete = po_lex_obsolete; return STRING; } @@ -576,12 +592,20 @@ po_gram_lex () c = keyword_p (buf); if (c == NAME) - po_gram_lval.string = xstrdup (buf); + { + po_gram_lval.string.string = xstrdup (buf); + po_gram_lval.string.pos = gram_pos; + po_gram_lval.string.obsolete = po_lex_obsolete; + } + else + { + po_gram_lval.pos.pos = gram_pos; + po_gram_lval.pos.obsolete = po_lex_obsolete; + } return c; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - /* I know, we don't need numbers, yet. */ bufpos = 0; for (;;) { @@ -608,13 +632,19 @@ po_gram_lex () buf[bufpos] = 0; - po_gram_lval.number = atol (buf); + po_gram_lval.number.number = atol (buf); + po_gram_lval.number.pos = gram_pos; + po_gram_lval.number.obsolete = po_lex_obsolete; return NUMBER; case '[': + po_gram_lval.pos.pos = gram_pos; + po_gram_lval.pos.obsolete = po_lex_obsolete; return '['; case ']': + po_gram_lval.pos.pos = gram_pos; + po_gram_lval.pos.obsolete = po_lex_obsolete; return ']'; default: diff --git a/src/po-lex.h b/src/po-lex.h index 4beb7bc..279382a 100644 --- a/src/po-lex.h +++ b/src/po-lex.h @@ -47,6 +47,9 @@ extern const char *po_lex_charset; extern iconv_t po_lex_iconv; #endif +/* Nonzero if obsolete entries shall be considered as valid. */ +extern int pass_obsolete_entries; + /* Open the PO file FNAME and prepare its lexical analysis. */ extern void lex_open PARAMS ((const char *__fname)); @@ -138,7 +141,6 @@ struct msgstr_def { char *msgstr; size_t msgstr_len; - lex_pos_ty pos; }; #endif |