diff options
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | Makefile | 41 | ||||
-rw-r--r-- | _examples/de_DE.utf8/LC_MESSAGES/example.mo | bin | 614 -> 0 bytes | |||
-rw-r--r-- | _examples/de_DE.utf8/example.pot | 37 | ||||
-rw-r--r-- | _examples/es_MX.utf8/LC_MESSAGES/example.mo | bin | 614 -> 0 bytes | |||
-rw-r--r-- | _examples/es_MX.utf8/example.pot | 37 | ||||
-rw-r--r-- | deps.mk | 4 | ||||
-rw-r--r-- | gettext_test.go | 67 | ||||
-rwxr-xr-x | mkdeps.sh | 5 | ||||
-rw-r--r-- | po/tests/de.po | 48 | ||||
-rw-r--r-- | po/tests/es.po | 48 | ||||
-rw-r--r-- | po/tests/po4a.cfg | 3 | ||||
-rw-r--r-- | po/tests/tests.pot | 37 | ||||
-rw-r--r-- | src/gotext.go | 40 | ||||
-rw-r--r-- | tests/functional/api-usage/gotext.go | 64 |
15 files changed, 257 insertions, 178 deletions
@@ -1,8 +1,8 @@ !/doc/*.adoc /doc/* -/src/version.go +/po/*/*.mo +/src/meta.go /*.bin -/*.db /src/*.a /src/*.bin /src/*cgo* @@ -24,7 +24,7 @@ GOLDFLAGS = -L $(GOLIBDIR) .SUFFIXES: -.SUFFIXES: .go .a .c .o .bin .bin-check .adoc +.SUFFIXES: .go .a .c .o .bin .bin-check .adoc .po .mo .c.o: $(CC) $(CFLAGS) -o $@ -c $< @@ -32,7 +32,7 @@ GOLDFLAGS = -L $(GOLIBDIR) .go.a: go tool compile -I $(@D) $(GOCFLAGS) -o $@ -p $(*F) \ `find $< $$(if [ $(*F) != main ]; then \ - echo src/$(NAME).go src/version.go; fi) | uniq` + echo src/$(NAME).go src/meta.go; fi) | uniq` .a.bin: go tool link -L $(@D) $(GOLDFLAGS) -o $@ --extldflags '$(LDLIBS)' $< @@ -40,6 +40,9 @@ GOLDFLAGS = -L $(GOLIBDIR) .adoc: asciidoctor -b manpage -o $@ $< +.po.mo: + msgfmt -cfv -o $@ $< + all: @@ -53,6 +56,7 @@ functional-tests/lib.a = $(functional-tests/lib.go:.go=.a) fuzz-targets/lib.a = $(fuzz-targets/lib.go:.go=.a) benchmarks/lib.a = $(benchmarks/lib.go:.go=.a) manpages.N = $(manpages.N.adoc:.adoc=) +sources.mo = $(sources.po:.po=.mo) cgo.go = \ src/_cgo_import.go \ @@ -73,24 +77,27 @@ objects = \ sources = \ src/$(NAME).go \ - src/version.go \ + src/meta.go \ src/main.go \ derived-assets = \ - src/version.go \ + src/meta.go \ $(objects) \ $(libs.a) \ $(mains.a) \ $(mains.bin) \ $(NAME).bin \ $(manpages.N) \ + $(sources.mo) \ + locale/.gitignore \ side-assets = \ src/_cgo_export.h \ src/_cgo_main.c \ tests/fuzz/corpus/ \ tests/benchmarks/*/main.txt \ + locale/ \ @@ -101,7 +108,7 @@ all: $(derived-assets) $(objects): Makefile deps.mk $(libs.a): Makefile deps.mk -$(libs.a): src/$(NAME).go src/version.go +$(libs.a): src/$(NAME).go src/meta.go $(libs.a): $(cgo.go) $(cgo.o) $(cgo.go) $(cgo.c) $(cgo.o): src/_cgo_.o @@ -114,27 +121,35 @@ src/_cgo_import.go: src/_cgo_.o go tool cgo --dynpackage $(NAME) --dynimport src/_cgo_.o --dynout $@ src/$(NAME).a tests/$(NAME).a $(functional-tests/lib.a) $(benchmarks/lib.a): - go tool compile $(GOCFLAGS) -o $@ -p $(*F) $(cgo.go) src/version.go \ + go tool compile $(GOCFLAGS) -o $@ -p $(*F) $(cgo.go) src/meta.go \ `find $*.go | grep -Ev '^src/$(NAME)\.go$$'` go tool pack r $@ $(cgo.o) $(fuzz-targets/lib.a): go tool compile $(GOCFLAGS) -o $@ -p $(NAME) -d=libfuzzer \ - $*.go $(cgo.go) src/version.go + $*.go $(cgo.go) src/meta.go go tool pack r $@ $(cgo.o) -src/version.go: Makefile - echo 'package $(NAME); const Version = "$(VERSION)"' > $@ +src/meta.go: Makefile + echo 'package $(NAME)' > $@ + echo 'const Version = "$(VERSION)"' >> $@ + echo 'const Name = "$(NAME)"' >> $@ + echo 'const LOCALEDIR = "$(LOCALEDIR)"' >> $@ $(NAME).bin: src/main.bin ln -fs src/main.bin $@ +locale/.gitignore: po/tests/de.mo po/tests/es.mo + instool $(@D) install mo $(sources.mo) + echo '*' > $@ + tests.bin-check = \ tests/main.bin-check \ $(functional-tests/main.go:.go=.bin-check) \ +tests/functional/api-usage/bin-check: locale/dir.sentinel $(tests.bin-check): $(EXEC)$*.bin @@ -181,9 +196,15 @@ bench: $(benchmarks/main.bin-check) -i18n: +i18n-doc: po4a po/doc/po4a.cfg +i18n-tests: + gotext tests/functional/api-usage/gotext.go > po/tests/tests.pot + po4a po/tests/po4a.cfg + +i18n: i18n-doc i18n-tests + ## Remove *all* derived artifacts produced during the build. diff --git a/_examples/de_DE.utf8/LC_MESSAGES/example.mo b/_examples/de_DE.utf8/LC_MESSAGES/example.mo Binary files differdeleted file mode 100644 index 9c8c27d..0000000 --- a/_examples/de_DE.utf8/LC_MESSAGES/example.mo +++ /dev/null diff --git a/_examples/de_DE.utf8/example.pot b/_examples/de_DE.utf8/example.pot deleted file mode 100644 index 9261267..0000000 --- a/_examples/de_DE.utf8/example.pot +++ /dev/null @@ -1,37 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -#, fuzzy -msgid "" -msgstr "Project-Id-Version: PACKAGE VERSION\n" - "Report-Msgid-Bugs-To: \n" - "POT-Creation-Date: 2012-10-06 15:47-0500\n" - "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" - "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" - "Language-Team: LANGUAGE <LL@li.org>\n" - "Language: \n" - "MIME-Version: 1.0\n" - "Content-Type: text/plain; charset=UTF-8\n" - "Content-Transfer-Encoding: 8bit\n" - "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" - -#: gettext_test.go:32 gettext_test.go:40 -#, c-format -msgid "An apple" -msgid_plural "%d apples" -msgstr[0] "Ein Apfel" -msgstr[1] "%d Äpfel" - -#: gettext_test.go:56 -msgid "Good bye!" -msgstr "Auf Wiedersehen!" - -#: gettext_test.go:48 -msgid "Good morning" -msgstr "Guten morgen" - -#: gettext_test.go:24 -msgid "Hello, world!" -msgstr "Hallo, Welt!" diff --git a/_examples/es_MX.utf8/LC_MESSAGES/example.mo b/_examples/es_MX.utf8/LC_MESSAGES/example.mo Binary files differdeleted file mode 100644 index ce1ebca..0000000 --- a/_examples/es_MX.utf8/LC_MESSAGES/example.mo +++ /dev/null diff --git a/_examples/es_MX.utf8/example.pot b/_examples/es_MX.utf8/example.pot deleted file mode 100644 index b490af0..0000000 --- a/_examples/es_MX.utf8/example.pot +++ /dev/null @@ -1,37 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -#, fuzzy -msgid "" -msgstr "Project-Id-Version: PACKAGE VERSION\n" - "Report-Msgid-Bugs-To: \n" - "POT-Creation-Date: 2012-10-06 15:47-0500\n" - "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" - "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" - "Language-Team: LANGUAGE <LL@li.org>\n" - "Language: \n" - "MIME-Version: 1.0\n" - "Content-Type: text/plain; charset=UTF-8\n" - "Content-Transfer-Encoding: 8bit\n" - "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" - -#: gettext_test.go:32 gettext_test.go:40 -#, c-format -msgid "An apple" -msgid_plural "%d apples" -msgstr[0] "Una manzana" -msgstr[1] "%d manzanas" - -#: gettext_test.go:56 -msgid "Good bye!" -msgstr "¡Hasta luego!" - -#: gettext_test.go:48 -msgid "Good morning" -msgstr "Buenos días" - -#: gettext_test.go:24 -msgid "Hello, world!" -msgstr "¡Hola mundo!" @@ -20,6 +20,10 @@ manpages.N.adoc = \ doc/gotext.fr.0.adoc \ doc/gotext.pt.0.adoc \ +sources.po = \ + po/tests/de.po \ + po/tests/es.po \ + functional-tests/lib.go = \ tests/functional/api-usage/gotext.go \ diff --git a/gettext_test.go b/gettext_test.go deleted file mode 100644 index a22bbc6..0000000 --- a/gettext_test.go +++ /dev/null @@ -1,67 +0,0 @@ -package gettext - -import ( - "os" - "testing" - - "github.com/stretchr/testify/assert" -) - -const ( - spanishMexico = "es_MX.utf8" - deutschDeutschland = "de_DE.utf8" - frenchFrance = "fr_FR.utf8" -) - -// a setUp would be nice -func init() { - textDomain := "example" - BindTextdomain(textDomain, "_examples/") - Textdomain(textDomain) -} - -func TestSpanish(t *testing.T) { - os.Setenv("LANGUAGE", spanishMexico) - SetLocale(LcAll, "") - - assert.Equal(t, "¡Hola mundo!", Gettext("Hello, world!")) - - assert.Equal(t, "Una manzana", Sprintf(NGettext("An apple", "%d apples", 1), 1, "garbage")) - - assert.Equal(t, "3 manzanas", Sprintf(NGettext("An apple", "%d apples", 3), 3)) - - assert.Equal(t, "Buenos días", Gettext("Good morning")) - - assert.Equal(t, "¡Hasta luego!", Gettext("Good bye!")) -} - -func TestDeutsch(t *testing.T) { - os.Setenv("LANGUAGE", deutschDeutschland) - SetLocale(LcAll, "") - - assert.Equal(t, "Hallo, Welt!", Gettext("Hello, world!")) - - assert.Equal(t, "Ein Apfel", Sprintf(NGettext("An apple", "%d apples", 1), 1, "garbage")) - - assert.Equal(t, "3 Äpfel", Sprintf(NGettext("An apple", "%d apples", 3), 3)) - - assert.Equal(t, "Guten morgen", Gettext("Good morning")) - - assert.Equal(t, "Auf Wiedersehen!", Gettext("Good bye!")) -} - -func TestFrench(t *testing.T) { - // Note that we don't have a french translation. - os.Setenv("LANGUAGE", frenchFrance) - SetLocale(LcAll, "") - - assert.Equal(t, "Hello, world!", Gettext("Hello, world!")) - - assert.Equal(t, "An apple", Sprintf(NGettext("An apple", "%d apples", 1), 1, "garbage")) - - assert.Equal(t, "3 apples", Sprintf(NGettext("An apple", "%d apples", 3), 3)) - - assert.Equal(t, "Good morning", Gettext("Good morning")) - - assert.Equal(t, "Good bye!", Gettext("Good bye!")) -} @@ -17,9 +17,14 @@ docs() { find doc/*.adoc } +pos() { + find po/ -name '*.po' | grep -v '^po/doc/' +} + libs | varlist 'libs.go' mains | varlist 'mains.go' docs | varlist 'manpages.N.adoc' +pos | varlist 'sources.po' find tests/functional/*/*.go -not -name main.go | varlist 'functional-tests/lib.go' find tests/functional/*/main.go | varlist 'functional-tests/main.go' diff --git a/po/tests/de.po b/po/tests/de.po new file mode 100644 index 0000000..284208a --- /dev/null +++ b/po/tests/de.po @@ -0,0 +1,48 @@ +# German translations for package. +# Copyright (C) 2025 THE 'S COPYRIGHT HOLDER +# This file is distributed under the same license as the package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: EMAIL\n" +"POT-Creation-Date: 2025-05-12 07:34-0300\n" +"PO-Revision-Date: 2025-05-12 07:28-0300\n" +"Last-Translator: EuAndreh <eu@euandre.org>\n" +"Language-Team: none\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: tests/functional/api-usage/gotext.go:23 +#: tests/functional/api-usage/gotext.go:34 +#: tests/functional/api-usage/gotext.go:46 +msgid "Good morning" +msgstr "Guten Morgen" + +#: tests/functional/api-usage/gotext.go:24 +#: tests/functional/api-usage/gotext.go:35 +#: tests/functional/api-usage/gotext.go:47 +msgid "Good bye!" +msgstr "Auf Wiedersehen!" + +#: tests/functional/api-usage/gotext.go:20 +#: tests/functional/api-usage/gotext.go:31 +#: tests/functional/api-usage/gotext.go:43 +msgid "Hello, world!" +msgstr "Hallo, Welt!" + +#: tests/functional/api-usage/gotext.go:21 +#: tests/functional/api-usage/gotext.go:22 +#: tests/functional/api-usage/gotext.go:32 +#: tests/functional/api-usage/gotext.go:33 +#: tests/functional/api-usage/gotext.go:44 +#: tests/functional/api-usage/gotext.go:45 +#, c-format +msgid "An apple" +msgid_plural "%d apples" +msgstr[0] "Ein Apfel" +msgstr[1] "%d Äpfel" diff --git a/po/tests/es.po b/po/tests/es.po new file mode 100644 index 0000000..3da3dcb --- /dev/null +++ b/po/tests/es.po @@ -0,0 +1,48 @@ +# Spanish translations for package. +# Copyright (C) 2025 THE 'S COPYRIGHT HOLDER +# This file is distributed under the same license as the package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: EMAIL\n" +"POT-Creation-Date: 2025-05-12 07:34-0300\n" +"PO-Revision-Date: 2025-05-12 07:33-0300\n" +"Last-Translator: EuAndreh <eu@euandre.org>\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: tests/functional/api-usage/gotext.go:23 +#: tests/functional/api-usage/gotext.go:34 +#: tests/functional/api-usage/gotext.go:46 +msgid "Good morning" +msgstr "Buenos días" + +#: tests/functional/api-usage/gotext.go:24 +#: tests/functional/api-usage/gotext.go:35 +#: tests/functional/api-usage/gotext.go:47 +msgid "Good bye!" +msgstr "¡Hasta luego!" + +#: tests/functional/api-usage/gotext.go:20 +#: tests/functional/api-usage/gotext.go:31 +#: tests/functional/api-usage/gotext.go:43 +msgid "Hello, world!" +msgstr "¡Hola, mundo!" + +#: tests/functional/api-usage/gotext.go:21 +#: tests/functional/api-usage/gotext.go:22 +#: tests/functional/api-usage/gotext.go:32 +#: tests/functional/api-usage/gotext.go:33 +#: tests/functional/api-usage/gotext.go:44 +#: tests/functional/api-usage/gotext.go:45 +#, c-format +msgid "An apple" +msgid_plural "%d apples" +msgstr[0] "Una manzana" +msgstr[1] "%d manzanas" diff --git a/po/tests/po4a.cfg b/po/tests/po4a.cfg new file mode 100644 index 0000000..35a5291 --- /dev/null +++ b/po/tests/po4a.cfg @@ -0,0 +1,3 @@ +[options] --keep 0 --master-charset UTF-8 --localized-charset UTF-8 --addendum-charset UTF-8 + +[po_directory] po/tests/ diff --git a/po/tests/tests.pot b/po/tests/tests.pot new file mode 100644 index 0000000..6421a90 --- /dev/null +++ b/po/tests/tests.pot @@ -0,0 +1,37 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "Project-Id-Version: \n" + "Report-Msgid-Bugs-To: EMAIL\n" + "POT-Creation-Date: 2025-05-12 07:34-0300\n" + "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" + "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" + "Language-Team: LANGUAGE <LL@li.org>\n" + "Language: \n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" + +#: tests/functional/api-usage/gotext.go:23 tests/functional/api-usage/gotext.go:34 tests/functional/api-usage/gotext.go:46 +msgid "Good morning" +msgstr "" + +#: tests/functional/api-usage/gotext.go:24 tests/functional/api-usage/gotext.go:35 tests/functional/api-usage/gotext.go:47 +msgid "Good bye!" +msgstr "" + +#: tests/functional/api-usage/gotext.go:20 tests/functional/api-usage/gotext.go:31 tests/functional/api-usage/gotext.go:43 +msgid "Hello, world!" +msgstr "" + +#: tests/functional/api-usage/gotext.go:21 tests/functional/api-usage/gotext.go:22 tests/functional/api-usage/gotext.go:32 tests/functional/api-usage/gotext.go:33 tests/functional/api-usage/gotext.go:44 tests/functional/api-usage/gotext.go:45 +#, c-format +msgid "An apple" +msgid_plural "%d apples" +msgstr[0] "" +msgstr[1] "" + diff --git a/src/gotext.go b/src/gotext.go index b802d86..73190c3 100644 --- a/src/gotext.go +++ b/src/gotext.go @@ -249,7 +249,7 @@ msgstr "Project-Id-Version: %s\n" "Language-Team: LANGUAGE <LL@li.org>\n" "Language: \n" "MIME-Version: 1.0\n" - "Content-Type: text/plain; charset=CHARSET\n" + "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" `, opts.PackageName, opts.MsgIDBugsAddress, formatTime()) @@ -445,41 +445,31 @@ func Main() { writePotFile(out) } +// FIXME: are these comments useful var ( // LcAll is for all of the locale. - LcAll = uint(C.LC_ALL) + LC_ALL = uint(C.LC_ALL) - // LcCollate is for regular expression matching (it determines the meaning of + // LC_Collate is for regular expression matching (it determines the meaning of // range expressions and equivalence classes) and string collation. - LcCollate = uint(C.LC_COLLATE) + LC_COLLATE = uint(C.LC_COLLATE) - // LcCtype is for regular expression matching, character classification, + // LC_Ctype is for regular expression matching, character classification, // conversion, case-sensitive comparison, and wide character functions. - LcCtype = uint(C.LC_CTYPE) + LC_CTYPE = uint(C.LC_CTYPE) - // LcMessages is for localizable natural-language messages. - LcMessages = uint(C.LC_MESSAGES) + // LC_Messages is for localizable natural-language messages. + LC_MESSAGES = uint(C.LC_MESSAGES) - // LcMonetary is for monetary formatting. - LcMonetary = uint(C.LC_MONETARY) + // LC_Monetary is for monetary formatting. + LC_MONETARY = uint(C.LC_MONETARY) - // LcNumeric is for number formatting (such as the decimal point and the + // LC_Numeric is for number formatting (such as the decimal point and the // thousands separator). - LcNumeric = uint(C.LC_NUMERIC) + LC_NUMERIC = uint(C.LC_NUMERIC) - // LcTime is for time and date formatting. - LcTime = uint(C.LC_TIME) -) - -// Deprecated but kept for backwards compatibility. -var ( - LC_ALL = LcAll - LC_COLLATE = LcCollate - LC_CTYPE = LcCtype - LC_MESSAGES = LcMessages - LC_MONETARY = LcMonetary - LC_NUMERIC = LcNumeric - LC_TIME = LcTime + // LC_Time is for time and date formatting. + LC_TIME = uint(C.LC_TIME) ) // SetLocale sets the program's current locale. diff --git a/tests/functional/api-usage/gotext.go b/tests/functional/api-usage/gotext.go index 36d1327..7ea7119 100644 --- a/tests/functional/api-usage/gotext.go +++ b/tests/functional/api-usage/gotext.go @@ -1,4 +1,68 @@ package gotext +import ( + "os" + + g "gobang" +) + + + func MainTest() { + g.Init() + Init("tests", "locale/") + + g.Testing("Español", func() { + os.Setenv("LANGUAGE", "es_MX.UTF-8") + SetLocale(LC_ALL, "") + + g.TAssertEqual(Gettext("Hello, world!"), "¡Hola, mundo!") + g.TAssertEqual(Gettext("Good morning"), "Buenos días") + g.TAssertEqual(Gettext("Good bye!"), "¡Hasta luego!") + g.TAssertEqual(Sprintf( + NGettext("An apple", "%d apples", 1), + 1, + "garbage", + ), "Una manzana") + g.TAssertEqual(Sprintf( + NGettext("An apple", "%d apples", 3), + 3, + ), "3 manzanas") + }) + + g.Testing("Deutsch", func() { + os.Setenv("LANGUAGE", "de_DE.UTF-8") + SetLocale(LC_ALL, "") + + g.TAssertEqual(Gettext("Hello, world!"), "Hallo, Welt!") + g.TAssertEqual(Gettext("Good morning"), "Guten Morgen") + g.TAssertEqual(Gettext("Good bye!"), "Auf Wiedersehen!") + g.TAssertEqual(Sprintf( + NGettext("An apple", "%d apples", 1), + 1, + "garbage", + ), "Ein Apfel") + g.TAssertEqual(Sprintf( + NGettext("An apple", "%d apples", 3), + 3, + ), "3 Äpfel") + }) + + g.Testing("Français", func() { + os.Setenv("LANGUAGE", "fr_FR.UTF-8") + SetLocale(LC_ALL, "") + + g.TAssertEqual(Gettext("Hello, world!"), "Hello, world!") + g.TAssertEqual(Gettext("Good morning"), "Good morning") + g.TAssertEqual(Gettext("Good bye!"), "Good bye!") + g.TAssertEqual(Sprintf( + NGettext("An apple", "%d apples", 1), + 1, + "garbage", + ), "An apple") + g.TAssertEqual(Sprintf( + NGettext("An apple", "%d apples", 3), + 3, + ), "3 apples") + }) } |