# SOME DESCRIPTIVE TITLE # Copyright (C) YEAR The FreeBSD Project # This file is distributed under the same license as the FreeBSD Documentation package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: FreeBSD Documentation VERSION\n" "POT-Creation-Date: 2025-11-08 16:17+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: YAML Front Matter: description #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:1 #, no-wrap msgid "Localization and Internationalization - L10N and I18N in FreeBSD" msgstr "" #. type: YAML Front Matter: title #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:1 #, no-wrap msgid "Chapter 4. Localization and Internationalization - L10N and I18N" msgstr "" #. type: Title = #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:15 #, no-wrap msgid "Localization and Internationalization - L10N and I18N" msgstr "" #. type: Title == #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:53 #, no-wrap msgid "Programming I18N Compliant Applications" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:60 msgid "" "To make your application more useful for speakers of other languages, we " "hope that you will program I18N compliant. The GNU gcc compiler and GUI " "libraries like QT and GTK support I18N through special handling of strings. " "Making a program I18N compliant is very easy. It allows contributors to " "port your application to other languages quickly. Refer to the library " "specific I18N documentation for more details." msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:64 msgid "" "In contrast with common perception, I18N compliant code is easy to write. " "Usually, it only involves wrapping your strings with library specific " "functions. In addition, please be sure to allow for wide or multibyte " "character support." msgstr "" #. type: Title === #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:65 #, no-wrap msgid "A Call to Unify the I18N Effort" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:70 msgid "" "It has come to our attention that the individual I18N/L10N efforts for each " "country has been repeating each others' efforts. Many of us have been " "reinventing the wheel repeatedly and inefficiently. We hope that the " "various major groups in I18N could congregate into a group effort similar to " "the Core Team's responsibility." msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:73 msgid "" "Currently, we hope that, when you write or port I18N programs, you would " "send it out to each country's related FreeBSD mailing list for testing. In " "the future, we hope to create applications that work in all the languages " "out-of-the-box without dirty hacks." msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:76 msgid "" "The {freebsd-i18n} has been established. If you are an I18N/L10N developer, " "please send your comments, ideas, questions, and anything you deem related " "to it." msgstr "" #. type: Title === #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:77 #, no-wrap msgid "Perl and Python" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:81 msgid "" "Perl and Python have I18N and wide character handling libraries. Please use " "them for I18N compliance." msgstr "" #. type: Title == #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:83 #, no-wrap msgid "Localized Messages with POSIX.1 Native Language Support (NLS)" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:87 msgid "" "Beyond the basic I18N functions, like supporting various input encodings or " "supporting national conventions, such as the different decimal separators, " "at a higher level of I18N, it is possible to localize the messages written " "to the output by the various programs. A common way of doing this is using " "the POSIX.1 NLS functions, which are provided as a part of the FreeBSD base " "system." msgstr "" #. type: Title === #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:89 #, no-wrap msgid "Organizing Localized Messages into Catalog Files" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:95 msgid "" "POSIX.1 NLS is based on catalog files, which contain the localized messages " "in the desired encoding. The messages are organized into sets and each " "message is identified by an integer number in the containing set. The " "catalog files are conventionally named after the locale they contain " "localized messages for, followed by the `.msg` extension. For instance, the " "Hungarian messages for ISO8859-2 encoding should be stored in a file called " "[.filename]#hu_HU.ISO8859-2#." msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:100 msgid "" "These catalog files are common text files that contain the numbered " "messages. It is possible to write comments by starting the line with a `$` " "sign. Set boundaries are also separated by special comments, where the " "keyword `set` must directly follow the `$` sign. The `set` keyword is then " "followed by the set number. For example:" msgstr "" #. type: delimited block . 4 #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:104 #, no-wrap msgid "$set 1\n" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:108 msgid "" "The actual message entries start with the message number and followed by the " "localized message. The well-known modifiers from man:printf[3] are accepted:" msgstr "" #. type: delimited block . 4 #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:112 #, no-wrap msgid "15 \"File not found: %s\\n\"\n" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:118 msgid "" "The language catalog files have to be compiled into a binary form before " "they can be opened from the program. This conversion is done with the " "man:gencat[1] utility. Its first argument is the filename of the compiled " "catalog and its further arguments are the input catalogs. The localized " "messages can also be organized into more catalog files and then all of them " "can be processed with man:gencat[1]." msgstr "" #. type: Title === #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:120 #, no-wrap msgid "Using the Catalog Files from the Source Code" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:131 msgid "" "Using the catalog files is simple. To use the related functions, " "[.filename]#nl_types.h# must be included. Before using a catalog, it has to " "be opened with man:catopen[3]. The function takes two arguments. The first " "parameter is the name of the installed and compiled catalog. Usually, the " "name of the program is used, such as grep. This name will be used when " "looking for the compiled catalog file. The man:catopen[3] call looks for " "this file in [.filename]#/usr/share/nls/locale/catname# and in [.filename]#/" "usr/local/share/nls/locale/catname#, where `locale` is the locale set and " "`catname` is the catalog name being discussed. The second parameter is a " "constant, which can have two values:" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:133 msgid "" "`NL_CAT_LOCALE`, which means that the used catalog file will be based on " "`LC_MESSAGES`." msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:134 msgid "`0`, which means that `LANG` has to be used to open the proper catalog." msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:137 msgid "" "The man:catopen[3] call returns a catalog identifier of type `nl_catd`. " "Please refer to the manual page for a list of possible returned error codes." msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:140 msgid "" "After opening a catalog man:catgets[3] can be used to retrieve a message. " "The first parameter is the catalog identifier returned by man:catopen[3], " "the second one is the number of the set, the third one is the number of the " "messages, and the fourth one is a fallback message, which will be returned " "if the requested message cannot be retrieved from the catalog file." msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:142 msgid "" "After using the catalog file, it must be closed by calling man:catclose[3], " "which has one argument, the catalog id." msgstr "" #. type: Title === #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:144 #, no-wrap msgid "A Practical Example" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:147 msgid "" "The following example will demonstrate an easy solution on how to use NLS " "catalogs in a flexible way." msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:149 msgid "" "The below lines need to be put into a common header file of the program, " "which is included into all source files where localized messages are " "necessary:" msgstr "" #. type: delimited block . 4 #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:156 #, no-wrap msgid "" "#ifdef WITHOUT_NLS\n" "#define getstr(n)\t nlsstr[n]\n" "#else\n" "#include \n" msgstr "" #. type: delimited block . 4 #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:160 #, no-wrap msgid "" "extern nl_catd\t\t catalog;\n" "#define getstr(n)\t catgets(catalog, 1, n, nlsstr[n])\n" "#endif\n" msgstr "" #. type: delimited block . 4 #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:162 #, no-wrap msgid "extern char\t\t*nlsstr[];\n" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:165 msgid "" "Next, put these lines into the global declaration part of the main source " "file:" msgstr "" #. type: delimited block . 4 #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:172 #, no-wrap msgid "" "#ifndef WITHOUT_NLS\n" "#include \n" "nl_catd\t catalog;\n" "#endif\n" msgstr "" #. type: delimited block . 4 #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:182 #, no-wrap msgid "" "/*\n" " * Default messages to use when NLS is disabled or no catalog\n" " * is found.\n" " */\n" "char *nlsstr[] = {\n" " \"\",\n" "/* 1*/ \"some random message\",\n" "/* 2*/ \"some other message\"\n" "};\n" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:185 msgid "" "Next come the real code snippets, which open, read, and close the catalog:" msgstr "" #. type: delimited block . 4 #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:191 #, no-wrap msgid "" "#ifndef WITHOUT_NLS\n" "\tcatalog = catopen(\"myapp\", NL_CAT_LOCALE);\n" "#endif\n" msgstr "" #. type: delimited block . 4 #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:193 #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:197 #, no-wrap msgid "...\n" msgstr "" #. type: delimited block . 4 #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:195 #, no-wrap msgid "printf(getstr(1));\n" msgstr "" #. type: delimited block . 4 #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:201 #, no-wrap msgid "" "#ifndef WITHOUT_NLS\n" "\tcatclose(catalog);\n" "#endif\n" msgstr "" #. type: Title ==== #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:203 #, no-wrap msgid "Reducing Strings to Localize" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:207 msgid "" "There is a good way of reducing the strings that need to be localized by " "using libc error messages. This is also useful to just avoid duplication " "and provide consistent error messages for the common errors that can be " "encountered by a great many of programs." msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:209 msgid "First, here is an example that does not use libc error messages:" msgstr "" #. type: delimited block . 4 #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:216 #, no-wrap msgid "" "#include \n" "...\n" "if (!S_ISDIR(st.st_mode))\n" "\terrx(1, \"argument is not a directory\");\n" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:219 msgid "" "This can be transformed to print an error message by reading `errno` and " "printing an error message accordingly:" msgstr "" #. type: delimited block . 4 #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:229 #, no-wrap msgid "" "#include \n" "#include \n" "...\n" "if (!S_ISDIR(st.st_mode)) {\n" "\terrno = ENOTDIR;\n" "\terr(1, NULL);\n" "}\n" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:234 msgid "" "In this example, the custom string is eliminated, thus translators will have " "less work when localizing the program and users will see the usual \"Not a " "directory\" error message when they encounter this error. This message will " "probably seem more familiar to them. Please note that it was necessary to " "include [.filename]#errno.h# in order to directly access `errno`." msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:236 msgid "" "It is worth to note that there are cases when `errno` is set automatically " "by a preceding call, so it is not necessary to set it explicitly:" msgstr "" #. type: delimited block . 4 #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:243 #, no-wrap msgid "" "#include \n" "...\n" "if ((p = malloc(size)) == NULL)\n" "\terr(1, NULL);\n" msgstr "" #. type: Title === #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:246 #, no-wrap msgid "Making use of [.filename]#bsd.nls.mk#" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:251 msgid "" "Using the catalog files requires few repeatable steps, such as compiling the " "catalogs and installing them to the proper location. In order to simplify " "this process even more, [.filename]#bsd.nls.mk# introduces some macros. It " "is not necessary to include [.filename]#bsd.nls.mk# explicitly, it is pulled " "in from the common Makefiles, such as [.filename]#bsd.prog.mk# or " "[.filename]#bsd.lib.mk#." msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:255 msgid "" "Usually it is enough to define `NLSNAME`, which should have the catalog name " "mentioned as the first argument of man:catopen[3] and list the catalog files " "in `NLS` without their `.msg` extension. Here is an example, which makes it " "possible to to disable NLS when used with the code examples before. The " "`WITHOUT_NLS` man:make[1] variable has to be defined in order to build the " "program without NLS support." msgstr "" #. type: delimited block . 4 #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:265 #, no-wrap msgid "" ".if !defined(WITHOUT_NLS)\n" "NLS=\tes_ES.ISO8859-1\n" "NLS+=\thu_HU.ISO8859-2\n" "NLS+=\tpt_BR.ISO8859-1\n" ".else\n" "CFLAGS+=\t-DWITHOUT_NLS\n" ".endif\n" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/l10n/_index.adoc:272 msgid "" "Conventionally, the catalog files are placed under the [.filename]#nls# " "subdirectory and this is the default behavior of [.filename]#bsd.nls.mk#. " "It is possible, though to override the location of the catalogs with the " "`NLSSRCDIR` man:make[1] variable. The default name of the precompiled " "catalog files also follow the naming convention mentioned before. It can be " "overridden by setting the `NLSNAME` variable. There are other options to " "fine tune the processing of the catalog files but usually it is not needed, " "thus they are not described here. For further information on " "[.filename]#bsd.nls.mk#, please refer to the file itself, it is short and " "easy to understand." msgstr ""