Skip to content

locale: Make pot file generation stable - #8010

Merged
echoix merged 3 commits into
OSGeo:mainfrom
echoix:claude/prid-translation-churn-u8lrv1
Oct 5, 2026
Merged

echoix merged 3 commits into
OSGeo:mainfrom
echoix:claude/prid-translation-churn-u8lrv1

Conversation

@echoix

@echoix echoix commented Oct 3, 2026 •

Copy link
Copy Markdown
Member

Description

Stops locale/templates/grasslibs.pot from changing without any code change:

  1. libvector: build_sfa.c uses "%" PRId64 " vertices registered" (with a (grass_int64) cast) as the plural of "One vertex registered", like build_nat.c.
  2. locale: make pot sorts its xgettext input file lists with LC_ALL=C sort.

Motivation and context

"One vertex registered" is used with two different plural forms: "%" PRId64 " vertices registered" in build_nat.c and "%d vertices registered" in build_sfa.c (twice). A .pot file keeps one plural form per msgid, and xgettext keeps the first one it reads. The file lists come from find, whose order is not stable, so the template flips between the two forms. Each flip changes the msgid and marks the existing translations as fuzzy:

2026-03-28  27027a88  +msgid_plural "%<PRId64> vertices registered"
2026-04-15  ddf1ac92  -msgid_plural "%<PRId64> vertices registered"
2026-07-19  608efca1  +msgid_plural "%<PRId64> vertices registered"
2026-07-25  f040304d  -msgid_plural "%<PRId64> vertices registered"
2026-09-05  2a158b11  +msgid_plural "%<PRId64> vertices registered"

The first commit removes this conflict. The second makes the order deterministic. The next locale: Update translation files PR may change entries once, then it should stay stable.

CMake: no equivalent change is needed. locale/CMakeLists.txt only installs .mo files ("TODO: implement update and creation"), so make pot in locale/Makefile is the only path that generates the .pot files. If CMake gets .pot generation later, its file lists need sorting too (e.g. list(SORT ...)).

How has this been tested?

Locally, with GNU xgettext 0.21, running the same xgettext options as make pot on the sorted file list and on the same list reversed:

Tree lib .pot, sorted vs reversed order
Before (main) differs: the plural is %<PRId64> in one run and %d in the other
With this PR identical

The modules, wxPython and scripts domains also give the same msgids in both orders. The only difference, in the modules domain, is the placement of three #. GTC translator comments, which the sorted list makes deterministic.

On my fork, I ran the Periodic update workflow on this branch (update_po false). It built GRASS, ran make pot and make verify successfully, and opened a template-update PR against this branch. In that PR:

  • grasslibs.pot keeps msgid_plural "%<PRId64> vertices registered". The only changes are the build_sfa.c line numbers in the location comments, which moved with the edit, and the creation date.
  • grassmods.pot changes only in the order and duplication of three #. GTC translator comments.
  • grasswxpy.pot changes only in the creation date.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)

Checklist

  • PR title provides summary of the changes and starts with one of the pre-defined prefixes
  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.

AI disclosure: the root cause was found and the changes prepared with Claude Code. I reviewed the diff.

Claude added 2 commits October 3, 2026 20:50
…d_sfa.c

The message "One vertex registered" is used in build_nat.c with the plural
"%" PRId64 " vertices registered" and in build_sfa.c with "%d vertices
registered". A .pot file keeps only one plural form per singular msgid, and
xgettext keeps the first one it reads. The input file list comes from find,
whose order is not stable, so the template flipped between the two forms
from one update to the next. Each flip changed the msgid and made the
existing translations fuzzy.

Use the 64-bit form in build_sfa.c as well, casting the int counters, so
all three call sites share one msgid_plural.

Prepared with AI assistance (Claude Code); the root cause was found from
the history of locale/templates/grasslibs.pot.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The lists of files given to xgettext come from find, whose order depends
on the filesystem and can differ between runners. When the same msgid is
used with different plural forms, xgettext keeps the first one it reads, so
the generated .pot files could change without any change in the code.

Sort the lists with LC_ALL=C so that the order is the same everywhere.

Prepared with AI assistance (Claude Code).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@echoix
echoix requested a review from nilason October 3, 2026 22:16
@echoix

echoix commented Oct 3, 2026

Copy link
Copy Markdown
Member Author

@nilason This was another pain point

@github-actions github-actions Bot added vector Related to vector data processing C Related code is in C translation Message translation related libraries labels Oct 3, 2026
@nilason

nilason commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Let's cast to int64_t instead (now with C11, it is time to retire grass_int64 anyway I think).

@echoix

echoix commented Oct 5, 2026

Copy link
Copy Markdown
Member Author

Let's cast to int64_t instead (now with C11, it is time to retire grass_int64 anyway I think).

What do you mean? Anyways, if it’s a C-code change, then we need to change two other places; the problem comes from the fact that three copies of the string aren’t using the same placeholder type. This changes it to the same as the two others

@nilason

nilason commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Let's cast to int64_t instead (now with C11, it is time to retire grass_int64 anyway I think).

What do you mean? Anyways, if it’s a C-code change, then we need to change two other places; the problem comes from the fact that three copies of the string aren’t using the same placeholder type. This changes it to the same as the two others

Instead of cast to grass_int64, we should cast to int64_t directly, in practice they are the same:

typedef int64_t grass_int64;

(and now this block may be removed:

grass/include/grass/gis.h

Lines 657 to 669 in 000a00f

/* 64 bit signed integer */
#if HAVE_INT64_T
#include <sys/types.h>
typedef int64_t grass_int64;
#elif defined(__MINGW32__)
typedef __int64 grass_int64;
#elif HAVE_LONG_LONG_INT
typedef long long int grass_int64;
#elif HAVE_LARGEFILES
typedef off_t grass_int64;
#else
#error "no 64 bit integer available"
#endif

or at least be greatly reduced, but of course not with this PR.)

@nilason nilason left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what I meant, wouldn't this work with gettext?

Comment thread lib/vector/Vlib/build_sfa.c Outdated
Comment thread lib/vector/Vlib/build_sfa.c Outdated
@echoix

echoix commented Oct 5, 2026

Copy link
Copy Markdown
Member Author

This is what I meant, wouldn't this work with gettext?

Oh yes probably, but what about the PRId64? Is it ok like that, or you'd like to change the two other files that use PRId64 to something else?

@nilason

nilason commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

This is what I meant, wouldn't this work with gettext?

Oh yes probably, but what about the PRId64? Is it ok like that, or you'd like to change the two other files that use PRId64 to something else?

PRId64 is made to accompany int64_t, so that will be fine.

Co-authored-by: Nicklas Larsson <n_larsson@yahoo.com>
@echoix
echoix requested a review from nilason October 5, 2026 16:23
@echoix
echoix merged commit a5a14ae into OSGeo:main Oct 5, 2026
26 checks passed
@github-actions github-actions Bot added this to the 8.6.0 milestone Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C Related code is in C libraries translation Message translation related vector Related to vector data processing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants