git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v12 11/13] bisect--helper: `bisect_next_check` & bisect_voc shell function in C

From
Junio C Hamano <gitster@pobox.com>
Date
Aug 12, 2016, 18:49 UTC
Message-ID
<xmqqpopdx1on.fsf@gitster.mtv.corp.google.com>
In-Reply-To
<xmqq1t1tyi0z.fsf@gitster.mtv.corp.google.com>
Junio C Hamano <gitster@pobox.com> writes:
Show 10 quoted lines
> Pranit Bauva <pranit.bauva@gmail.com> writes:
>
>> +static int bisect_next_check(const struct bisect_terms *terms,
>> +			     const char *current_term)
>> +{
>> + ....
>> +		fprintf(stderr, N_("Warning: bisecting only with a %s commit\n"),
>> +			terms->term_bad.buf);
>
> Hmph, is this N_() and not _()?

I recall you saying that you are not familiar with i18n. As it is a good skill to have outside the context of this project, let's do a quick primer. GSoC is a learning experience ;-).

There is a runtime function "gettext()" that takes a string, which is typically a printf format string, and gives another string. You feed your message in the original language, meant to be used in the C locale, and the function gives it translated into the end-user's language, specified by environment variables like $LC_MESSAGES.

Since it is too cumbersome to write gettext() all the time, _() exists as a short-hand for it. So running this

	printf(_("Hello, world\n"));

would look up "Hello world\n" in database for the end-user's language, and shows the translated message instead.

By scanning the source text, you can extract these constant strings passed to gettext() or _(). This is done by the i18n coordinator with the "msgmerge" program. By doing so, we learn "Hello, world\n" must be translated, and then ask i18n team to translate it to their language. The result is what we have in the l10n database. They are in po/*.po files in our source tree.

Sometimes, the message you want to be translated may be in a variable, e.g.

        void greeting(const char *message)
        {
                printf(_(message));
        }
        int main(int ac, char **av)
        {
                int i;
                const char *message[] = {
                        "Hello, world\n",
                        "Goodbye, everybody\n",
                };
                for (i = 0; i < ARRAY_SIZE(message); i++)
                        greeting(message[i]);
        }

And scanning the source would not find "Hello, world\n" or "Goodby, everybody\n" must be translated. We do not want to do this:

                ...
                const char *message[] = {
*BAD*                   _("Hello, world\n"),
*BAD*                   _("Goodbye, everybody\n"),
                };
                ...

because we do *NOT* want to call gettext() there (we call the function at runtime inside greeting() instead). We use N_() to mark such messages, like so:

                ...
                const char *message[] = {
*GOOD*                  N_("Hello, world\n"),
*GOOD*                  N_("Goodbye, everybody\n"),
                };
                ...

The N_() macro is a no-op at runtime. It just is there so that "msgmerge" can notice that the constant string there is something that needs to be thrown into the l10n database.

As a concrete example:
Show 7 quoted lines
> @@ -24,6 +25,7 @@ static const char * const git_bisect_helper_usage[] = {
>  	N_("git bisect--helper --bisect-reset [<commit>]"),
>  	N_("git bisect--helper --bisect-write <state> <revision> <TERM_GOOD> <TERM_BAD> [<nolog>]"),
>  	N_("git bisect--helper --bisect-check-and-set-terms <command> <TERM_GOOD> <TERM_BAD>"),
> +	N_("git bisect--helper --bisect-next-check [<term>] <TERM_GOOD> <TERM_BAD"),
>  	NULL
>  };

this is such a use of N_(). You want to keep untranslated message in the git_bisect_helper_usage[] array, to be given to gettext(), or more likely its short-hand _(), when these usage strings are used, and make sure these strings will be in the l10n database so that translators will give you translations to them to be used at runtime.

Show 6 quoted lines
> +		/*
> +		 * have bad (or new) but not good (or old). We could bisect
> +		 * although this is less optimum.
> +		 */
> +		fprintf(stderr, N_("Warning: bisecting only with a %s commit\n"),
> +			terms->term_bad.buf);

This one wants to call gettext() function to give fprintf() the translated warning message. It should be _().

Show 6 quoted lines
> +		/*
> +		 * TRANSLATORS: Make sure to include [Y] and [n] in your
> +		 * translation. The program will only accept English input
> +		 * at this point.
> +		 */
> +		yesno = git_prompt(_("Are you sure [Y/n]? "), PROMPT_ECHO);
Just like this one.
Previous: Junio C HamanoNext: Pranit Bauva
Message 20 of 22 in “bisect--helper: use OPT_CMDMODE instead of OPT_BOOL”
  1. 01/13 bisect--helper: use OPT_CMDMODE instead of OPT_BOOLPranit Bauva, Aug 10, 2016
  2. 10/13 bisect--helper: `check_and_set_terms` shell function in CPranit Bauva, Aug 10, 2016
  3. 03/13 bisect--helper: `write_terms` shell function in CPranit Bauva, Aug 10, 2016
  4. 07/13 bisect--helper: `bisect_reset` shell function in CPranit Bauva, Aug 10, 2016
  5. 02/13 bisect: rewrite `check_term_format` shell function in CPranit Bauva, Aug 10, 2016
  6. 13/13 bisect--helper: `bisect_start` shell function partially in CPranit Bauva, Aug 10, 2016
  7. Junio C HamanoAug 12, 2016
  8. Pranit BauvaAug 13, 2016
  9. Christian CouderAug 13, 2016
  10. Pranit BauvaAug 13, 2016
  11. 12/13 bisect--helper: `get_terms` & `bisect_terms` shell function in CPranit Bauva, Aug 10, 2016
  12. 04/13 bisect--helper: `bisect_clean_state` shell function in CPranit Bauva, Aug 10, 2016
  13. Junio C HamanoAug 12, 2016
  14. 08/13 bisect--helper: `is_expected_rev` & `check_expected_revs` shell function in CPranit Bauva, Aug 10, 2016
  15. 05/13 t6030: explicitly test for bisection cleanupPranit Bauva, Aug 10, 2016
  16. Pranit BauvaAug 10, 2016
  17. 09/13 bisect--helper: `bisect_write` shell function in CPranit Bauva, Aug 10, 2016
  18. 11/13 bisect--helper: `bisect_next_check` & bisect_voc shell function in CPranit Bauva, Aug 10, 2016
  19. Junio C HamanoAug 12, 2016
  20. Junio C HamanoAug 12, 2016
  21. Pranit BauvaAug 13, 2016
  22. 06/13 wrapper: move is_empty_file() and rename it as is_empty_or_missing_file()Pranit Bauva, Aug 10, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.