From: Bruno Haible Date: Mon, 7 Mar 2005 19:43:33 +0000 (+0000) Subject: Use format strings as they are documented for GNU guile. X-Git-Tag: v0.14.3~46 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=911eb69a1a18ec8c42d43e650e299a2649b6fb99;p=thirdparty%2Fgettext.git Use format strings as they are documented for GNU guile. --- diff --git a/gettext-tools/src/ChangeLog b/gettext-tools/src/ChangeLog index 26bfd6c4c..edfb99ac8 100644 --- a/gettext-tools/src/ChangeLog +++ b/gettext-tools/src/ChangeLog @@ -1,3 +1,16 @@ +2005-02-26 Bruno Haible + + * format-scheme.c (format_arg_type): Add FAT_COMPLEX. Remove + FAT_FUNCTION. + (make_intersected_element): Simplify also the intersection with + FAT_COMPLEX. + (make_union_element): Simplify also the union with FAT_COMPLEX. + (IIC): New array. + (nocheck_params): Remove function. + (parse_upto): Remove handling of ~W, ~<, ~>. + Implement non-CL handling of ~C, ~I, ~_, ~/, ~T. + Implement handling of ~Y, ~!, ~Q, ~K. + 2005-02-26 Bruno Haible * format-scheme.c (parse_upto): Remove support for ~!. diff --git a/gettext-tools/src/format-scheme.c b/gettext-tools/src/format-scheme.c index b01aaedbd..326012a6e 100644 --- a/gettext-tools/src/format-scheme.c +++ b/gettext-tools/src/format-scheme.c @@ -42,9 +42,9 @@ #define VERIFY_LIST(list) verify_list (list) -/* Scheme format strings are described in the SLIB documentation, - section "Format Specification". They are implemented in SLIB's - format.scm and in guile-1.6.4/ice-9/format.scm. */ +/* Scheme format strings are described in the GNU guile documentation, + section "Formatted Output". They are implemented in + guile-1.6.4/ice-9/format.scm. */ /* Data structure describing format string derived constraints for an argument list. It is a recursive list structure. Structure sharing @@ -65,9 +65,9 @@ enum format_arg_type FAT_INTEGER_NULL, /* Type (OR INTEGER NULL). */ FAT_INTEGER, /* Meant for objects of type INTEGER. */ FAT_REAL, /* Meant for objects of type REAL. */ + FAT_COMPLEX, /* Meant for objects of type COMPLEX. */ FAT_LIST, /* Meant for proper lists. */ - FAT_FORMATSTRING, /* Format strings. */ - FAT_FUNCTION /* Function. */ + FAT_FORMATSTRING /* Format strings. */ }; struct format_arg @@ -1028,6 +1028,16 @@ make_intersected_element (struct format_arg *re, { re->type = e1->type; } + else if (e1->type == FAT_COMPLEX + && (e2->type == FAT_REAL || e2->type == FAT_INTEGER)) + { + re->type = e2->type; + } + else if (e2->type == FAT_COMPLEX + && (e1->type == FAT_REAL || e1->type == FAT_INTEGER)) + { + re->type = e1->type; + } else if (e1->type == e2->type) { re->type = e1->type; @@ -1040,8 +1050,8 @@ make_intersected_element (struct format_arg *re, } } else - /* Each of FAT_CHARACTER, FAT_INTEGER, FAT_LIST, FAT_FORMATSTRING, - FAT_FUNCTION matches only itself. Contradiction. */ + /* Each of FAT_CHARACTER, FAT_INTEGER, FAT_LIST, FAT_FORMATSTRING + matches only itself. Contradiction. */ return false; return true; @@ -1435,6 +1445,16 @@ make_union_element (struct format_arg *re, { re->type = e2->type; } + else if (e1->type == FAT_COMPLEX + && (e2->type == FAT_REAL || e2->type == FAT_INTEGER)) + { + re->type = e1->type; + } + else if (e2->type == FAT_COMPLEX + && (e1->type == FAT_REAL || e1->type == FAT_INTEGER)) + { + re->type = e2->type; + } else if (e1->type == FAT_LIST && is_empty_list (e1->list)) { if (e2->type == FAT_CHARACTER_INTEGER_NULL @@ -2301,6 +2321,9 @@ static const enum format_arg_type I [1] = { FAT_INTEGER_NULL }; static const enum format_arg_type II [2] = { FAT_INTEGER_NULL, FAT_INTEGER_NULL }; +static const enum format_arg_type IIC [3] = { + FAT_INTEGER_NULL, FAT_INTEGER_NULL, FAT_CHARACTER_NULL +}; static const enum format_arg_type ICCI [4] = { FAT_INTEGER_NULL, FAT_CHARACTER_NULL, FAT_CHARACTER_NULL, FAT_INTEGER_NULL }; @@ -2411,29 +2434,6 @@ check_params (struct format_arg_list **listp, } -/* Handle the parameters, without a priori type information. - For V params, add the constraint to the argument list. - Return false and fill in *invalid_reason if the format string is - invalid. */ -static bool -nocheck_params (struct format_arg_list **listp, - unsigned int paramcount, struct param *params, - unsigned int directives, char **invalid_reason) -{ - (void) directives; - (void) invalid_reason; - - for (; paramcount > 0; params++, paramcount--) - if (params->type == PT_V) - { - int position = params->value; - add_req_type_constraint (listp, position, FAT_CHARACTER_INTEGER_NULL); - } - - return true; -} - - /* ======================= The format string parser ======================= */ /* Parse a piece of format string, until the matching terminating format @@ -2582,12 +2582,14 @@ parse_upto (const char **formatp, add_req_type_constraint (&list, position++, FAT_OBJECT); break; - case 'W': case 'w': /* 22.3.4.3 FORMAT-WRITE */ - if (!check_params (&list, paramcount, params, 0, NULL, + case 'C': case 'c': /* FORMAT-CHARACTER */ + if (!check_params (&list, paramcount, params, 1, I, spec->directives, invalid_reason)) return false; - if (position >= 0) - add_req_type_constraint (&list, position++, FAT_OBJECT); + if (paramcount == 0 + || (paramcount == 1 && params[0].type == PT_NIL)) + if (position >= 0) + add_req_type_constraint (&list, position++, FAT_CHARACTER); break; case 'D': case 'd': /* 22.3.2.2 FORMAT-DECIMAL */ @@ -2623,14 +2625,6 @@ parse_upto (const char **formatp, add_req_type_constraint (&list, position++, FAT_OBJECT); break; - case 'C': case 'c': /* 22.3.1.1 FORMAT-CHARACTER */ - if (!check_params (&list, paramcount, params, 0, NULL, - spec->directives, invalid_reason)) - return false; - if (position >= 0) - add_req_type_constraint (&list, position++, FAT_CHARACTER); - break; - case 'F': case 'f': /* 22.3.3.1 FORMAT-FIXED-FLOAT */ if (!check_params (&list, paramcount, params, 5, IIICC, spec->directives, invalid_reason)) @@ -2656,25 +2650,43 @@ parse_upto (const char **formatp, add_req_type_constraint (&list, position++, FAT_REAL); break; + case 'I': case 'i': /* FORMAT-FIXED-FLOAT-COMPLEX */ + if (!check_params (&list, paramcount, params, 5, IIICC, + spec->directives, invalid_reason)) + return false; + if (position >= 0) + add_req_type_constraint (&list, position++, FAT_COMPLEX); + break; + + case 'Y': case 'y': /* FORMAT-PRETTY */ + if (!check_params (&list, paramcount, params, 0, NULL, + spec->directives, invalid_reason)) + return false; + if (position >= 0) + add_req_type_constraint (&list, position++, FAT_OBJECT); + break; + case '%': /* 22.3.1.2 FORMAT-TERPRI */ case '&': /* 22.3.1.3 FORMAT-FRESH-LINE */ + case '_': /* FORMAT-SPACE */ + case '/': /* FORMAT-TAB */ case '|': /* 22.3.1.4 FORMAT-PAGE */ case '~': /* 22.3.1.5 FORMAT-TILDE */ - case 'I': case 'i': /* 22.3.5.3 */ if (!check_params (&list, paramcount, params, 1, I, spec->directives, invalid_reason)) return false; break; + case '!': /* FORMAT-FORCE-OUTPUT */ case '\n': /* 22.3.9.3 #\Newline */ - case '_': /* 22.3.5.1 */ + case 'Q': case 'q': /* FORMAT-IMPLEMENTATION */ if (!check_params (&list, paramcount, params, 0, NULL, spec->directives, invalid_reason)) return false; break; - case 'T': case 't': /* 22.3.6.1 FORMAT-TABULATE */ - if (!check_params (&list, paramcount, params, 2, II, + case 'T': case 't': /* FORMAT-TABULATE */ + if (!check_params (&list, paramcount, params, 3, IIC, spec->directives, invalid_reason)) return false; break; @@ -2733,7 +2745,7 @@ parse_upto (const char **formatp, } break; - case '?': /* 22.3.7.6 FORMAT-INDIRECTION */ + case '?': case 'K': case 'k': /* 22.3.7.6 FORMAT-INDIRECTION */ if (!check_params (&list, paramcount, params, 0, NULL, spec->directives, invalid_reason)) return false; @@ -2751,23 +2763,6 @@ parse_upto (const char **formatp, } break; - case '/': /* 22.3.5.4 FORMAT-CALL-USER-FUNCTION */ - if (!check_params (&list, paramcount, params, 0, NULL, - spec->directives, invalid_reason)) - return false; - if (position >= 0) - add_req_type_constraint (&list, position++, FAT_OBJECT); - while (*format != '\0' && *format != '/') - format++; - if (*format == '\0') - { - *invalid_reason = - xstrdup (_("The string ends in the middle of a ~/.../ directive.")); - return false; - } - format++; - break; - case '(': /* 22.3.8.1 FORMAT-CASE-CONVERSION */ if (!check_params (&list, paramcount, params, 0, NULL, spec->directives, invalid_reason)) @@ -3143,55 +3138,6 @@ parse_upto (const char **formatp, *escapep = escape; return true; - case '<': /* 22.3.6.2, 22.3.5.2 FORMAT-JUSTIFICATION */ - if (!check_params (&list, paramcount, params, 4, IIIC, - spec->directives, invalid_reason)) - return false; - { - struct format_arg_list *sub_escape = NULL; - - *formatp = format; - *positionp = position; - *listp = list; - - for (;;) - { - int sub_separator = 0; - if (!parse_upto (formatp, positionp, listp, &sub_escape, - &sub_separator, spec, '>', true, - invalid_reason)) - return false; - if (!sub_separator) - break; - } - - format = *formatp; - position = *positionp; - list = *listp; - - /* ~< catches ~^. */ - if (sub_escape != NULL) - position = -1; - list = union (list, sub_escape); - } - break; - - case '>': /* 22.3.6.3 FORMAT-JUSTIFICATION-END */ - if (terminator != '>') - { - *invalid_reason = - xasprintf (_("Found '~%c' without matching '~%c'."), '>', '<'); - return false; - } - if (!check_params (&list, paramcount, params, 0, NULL, - spec->directives, invalid_reason)) - return false; - *formatp = format; - *positionp = position; - *listp = list; - *escapep = escape; - return true; - case '^': /* 22.3.9.2 FORMAT-UP-AND-OUT */ if (!check_params (&list, paramcount, params, 3, THREE, spec->directives, invalid_reason)) @@ -3417,15 +3363,15 @@ print_element (struct format_arg *element) case FAT_REAL: printf ("r"); break; + case FAT_COMPLEX: + printf ("C"); + break; case FAT_LIST: print_list (element->list); break; case FAT_FORMATSTRING: printf ("~"); break; - case FAT_FUNCTION: - printf ("f"); - break; default: abort (); } diff --git a/gettext-tools/tests/ChangeLog b/gettext-tools/tests/ChangeLog index 426558fae..8b5675297 100644 --- a/gettext-tools/tests/ChangeLog +++ b/gettext-tools/tests/ChangeLog @@ -1,3 +1,10 @@ +2005-02-26 Bruno Haible + + * format-scheme-1: Remove tests for ~W, ~_, ~T, ~/, ~<. Update or add + tests for ~Y, ~C, ~I, ~_, ~/, ~!, ~Q, ~T, ~K. + * format-scheme-2: Remove tests for ~W, ~<. Add tests for + ~!, ~Q, ~Y, ~I, ~/, ~K. + 2005-02-26 Bruno Haible * format-scheme-1: Remove test for #!. diff --git a/gettext-tools/tests/format-scheme-1 b/gettext-tools/tests/format-scheme-1 index 735274376..753ddf0ee 100755 --- a/gettext-tools/tests/format-scheme-1 +++ b/gettext-tools/tests/format-scheme-1 @@ -49,10 +49,10 @@ cat <<\EOF > f-sc-1.data "abc~v,v,v,vS" # Invalid: too many params "abc~v,v,v,v,5S" -# Valid: FORMAT-WRITE, (* | . *) -"abc~W" +# Valid: FORMAT-PRETTY, (* | . *) +"abc~Y" # Invalid: too many params -"abc~3W" +"abc~3Y" # Valid: FORMAT-DECIMAL, (i() c() c() i() i | . *) "abc~v,v,v,vD" # Invalid: too many params @@ -81,8 +81,10 @@ cat <<\EOF > f-sc-1.data "abc~2P" # Valid: FORMAT-CHARACTER, (c | . *) "abc~C" -# Invalid: too many params +# Valid: FORMAT-CHARACTER, ( | . *) "abc~4C" +# Invalid: too many params +"abc~4,4C" # Valid: FORMAT-FIXED-FLOAT, (i() i() i() c() c() r | . *) "abc~v,v,v,v,vF" # Invalid: too many params @@ -99,6 +101,8 @@ cat <<\EOF > f-sc-1.data "abc~v,v,v,v$" # Invalid: too many params "abc~v,v,v,v,5$" +# Valid: FORMAT-FIXED-FLOAT-COMPLEX, (C | .*) +"abc~I" # Valid: FORMAT-TERPRI, (i() | . *) "abc~v%" # Invalid: too many params @@ -107,6 +111,14 @@ cat <<\EOF > f-sc-1.data "abc~v&" # Invalid: too many params "abc~v,5&" +# Valid: FORMAT-SPACE, (i() | . *) +"abc~v_" +# Invalid: too many params +"abc~v,5_" +# Valid: FORMAT-TAB, (i() | . *) +"abc~v/" +# Invalid: too many params +"abc~v,5/" # Valid: FORMAT-PAGE, (i() | . *) "abc~v|" # Invalid: too many params @@ -115,14 +127,18 @@ cat <<\EOF > f-sc-1.data "abc~v~" # Invalid: too many params "abc~v,5~" -# Valid: underscore, ( | . *) -"abc~_" +# Valid: FORMAT-FORCE-OUTPUT, ( | . *) +"abc~!" +# Invalid: too many params +"abc~5!" +# Valid: FORMAT-IMPLEMENTATION, ( | . *) +"abc~Q" # Invalid: too many params -"abc~5_" -# Valid: FORMAT-TABULATE, (i() i() | . *) -"abc~v,vT" +"abc~5Q" +# Valid: FORMAT-TABULATE, (i() i() c() | . *) +"abc~v,v,vT" # Invalid: too many params -"abc~v,v,5T" +"abc~v,v,v,5T" # Valid: FORMAT-GOTO absolute, (* r c | . *) "abc~S~F~S~2@*~C" # Invalid: type incompatibility @@ -141,14 +157,12 @@ cat <<\EOF > f-sc-1.data "abc~@?" # Invalid: too many params "abc~4?" -# Valid: FORMAT-CALL-USER-FUNCTION, (* | . *) -"abc~/FOOBAR/" +# Valid: FORMAT-INDIRECTION, (~ ( | . *) | . *) +"abc~K" +# Valid: FORMAT-INDIRECTION, (~ | . *) +"abc~@K" # Invalid: too many params -"abc~4/FOOBAR/" -# Invalid: unterminated -"abc~/FOOB" -# Invalid: nesting mismatch -"abc~(~/FOOB~)/" +"abc~4K" # Valid: FORMAT-CASE-CONVERSION, (* | . *) "abc~(~S~)" # Invalid: too many params @@ -229,18 +243,8 @@ cat <<\EOF > f-sc-1.data "abc~:@{~[~D~]~}" # Invalid: separator "abc~{~D~;~C~}" -# Valid: FORMAT-JUSTIFICATION, (i() i() i() c() i | . *) -"abc~v,v,v,v<~D~>" -# Invalid: too many params -"abc~v,v,v,v,4<~D~>" -# Valid: separators -"abc~<~D~;~X~;def~>" -# Invalid: wrongly nested -"abc~<~(~>~)" # Invalid: wrongly nested "abc~{~(~}~)" -# Invalid: wrongly nested -"abc~{~<~}~>" # Valid: any number of arguments "abc~v,v,v,v,v!" # Invalid: type incompatibility between integer and list diff --git a/gettext-tools/tests/format-scheme-2 b/gettext-tools/tests/format-scheme-2 index 67d6cd07e..0be970f27 100755 --- a/gettext-tools/tests/format-scheme-2 +++ b/gettext-tools/tests/format-scheme-2 @@ -13,6 +13,12 @@ msgstr "xyz" # Invalid: invalid msgstr msgid "abc~~def" msgstr "xyz~" +# Valid: ~! doesn't count +msgid "abc~!def" +msgstr "xyz" +# Valid: ~Q doesn't count +msgid "abc~Qdef" +msgstr "xyz" # Valid: same argument msgid "abc~Ddef" msgstr "xyz~D" @@ -42,7 +48,7 @@ msgid "abc~4Sdef" msgstr "xyz~7S" # Valid: type compatibility msgid "abc~Sdef" -msgstr "xyz~W" +msgstr "xyz~Y" # Valid: type compatibility msgid "abc~Ddef" msgstr "xyz~B" @@ -85,12 +91,30 @@ msgstr "xyz~F" # Invalid: type incompatibility msgid "abc~Sdef" msgstr "xyz~C" +# Invalid: type incompatibility +msgid "abc~Fdef" +msgstr "xyz~I" +# Invalid: type incompatibility +msgid "abc~Ddef" +msgstr "xyz~I" +# Invalid: type incompatibility +msgid "abc~Sdef" +msgstr "xyz~I" +# Invalid: type incompatibility +msgid "abc~Cdef" +msgstr "xyz~I" # Valid: extra formatting msgid "abc~Ddef~S" -msgstr "xyz~D~_def~%~S" +msgstr "xyz~D~_d~/ef~%~S" +# Valid: extra force-output +msgid "abc~Ddef~S" +msgstr "xyz~Ddef~S~!" # Valid: FORMAT-GOTO doesn't consume an argument by itself msgid "abc~5@*~Ddef~C" msgstr "xyz~6@*~C~2@*uvw~5@*~R" +# Valid: ~? and ~K are equivalent +msgid "abc~?" +msgstr "xyz~K" # Invalid: @ matters msgid "abc~?" msgstr "xyz~@?" @@ -157,15 +181,6 @@ msgstr "xyz~{~1@*~C~2:*~D~^~1*~}" # Invalid: ~^ inside iteration depends on position msgid "abc~{~D ~^~C~}" msgstr "xyz~{~1@*~C~2:*~D~1*~^~}" -# Valid: justification is optional -msgid "abc~<~D~;~C~>" -msgstr "xyz~D~C" -# Valid: justification with different segmentation -msgid "abc~<~D ~D~;~C~;~S~S~>" -msgstr "xyz~<~D~;~D~C~S~;~S~>" -# Invalid: justification catches ~^ -msgid "abc~<~D~;~^~D~>~C" -msgstr "abc~D~^~D~C" EOF : ${MSGFMT=msgfmt}