DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 

(gettext.info.gz) c-format Flag

Info Catalog (gettext.info.gz) Marking (gettext.info.gz) Sources (gettext.info.gz) Special cases
 
 4.6 Special Comments preceding Keywords
 =======================================
 
 In C programs strings are often used within calls of functions from the
 `printf' family.  The special thing about these format strings is that
 they can contain format specifiers introduced with `%'.  Assume we have
 the code
 
      printf (gettext ("String `%s' has %d characters\n"), s, strlen (s));
 
 A possible German translation for the above string might be:
 
      "%d Zeichen lang ist die Zeichenkette `%s'"
 
    A C programmer, even if he cannot speak German, will recognize that
 there is something wrong here.  The order of the two format specifiers
 is changed but of course the arguments in the `printf' don't have.
 This will most probably lead to problems because now the length of the
 string is regarded as the address.
 
    To prevent errors at runtime caused by translations the `msgfmt'
 tool can check statically whether the arguments in the original and the
 translation string match in type and number.  If this is not the case
 and the `-c' option has been passed to `msgfmt', `msgfmt' will give an
 error and refuse to produce a MO file.  Thus consequent use of `msgfmt
 -c' will catch the error, so that it cannot cause cause problems at
 runtime.
 
 If the word order in the above German translation would be correct one
 would have to write
 
      "%2$d Zeichen lang ist die Zeichenkette `%1$s'"
 
 The routines in `msgfmt' know about this special notation.
 
    Because not all strings in a program must be format strings it is not
 useful for `msgfmt' to test all the strings in the `.po' file.  This
 might cause problems because the string might contain what looks like a
 format specifier, but the string is not used in `printf'.
 
    Therefore the `xgettext' adds a special tag to those messages it
 thinks might be a format string.  There is no absolute rule for this,
 only a heuristic.  In the `.po' file the entry is marked using the
 `c-format' flag in the `#,' comment line ( PO Files).
 
    The careful reader now might say that this again can cause problems.
 The heuristic might guess it wrong.  This is true and therefore
 `xgettext' knows about a special kind of comment which lets the
 programmer take over the decision.  If in the same line as or the
 immediately preceding line to the `gettext' keyword the `xgettext'
 program finds a comment containing the words `xgettext:c-format', it
 will mark the string in any case with the `c-format' flag.  This kind
 of comment should be used when `xgettext' does not recognize the string
 as a format string but it really is one and it should be tested.
 Please note that when the comment is in the same line as the `gettext'
 keyword, it must be before the string to be translated.
 
    This situation happens quite often.  The `printf' function is often
 called with strings which do not contain a format specifier.  Of course
 one would normally use `fputs' but it does happen.  In this case
 `xgettext' does not recognize this as a format string but what happens
 if the translation introduces a valid format specifier?  The `printf'
 function will try to access one of the parameters but none exists
 because the original code does not pass any parameters.
 
    `xgettext' of course could make a wrong decision the other way
 round, i.e. a string marked as a format string actually is not a format
 string.  In this case the `msgfmt' might give too many warnings and
 would prevent translating the `.po' file.  The method to prevent this
 wrong decision is similar to the one used above, only the comment to
 use must contain the string `xgettext:no-c-format'.
 
    If a string is marked with `c-format' and this is not correct the
 xgettext Invocation:: to see how the `--debug' option can be used for
 solving this problem.
 
Info Catalog (gettext.info.gz) Marking (gettext.info.gz) Sources (gettext.info.gz) Special cases
automatically generated byinfo2html