gettext: c-format Flag

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