FreeBSD Developers' Handbook | ||
---|---|---|
Zurück | Kapitel 4. Lokalisierung und Internationalisierung - L10N und I18N | Weiter |
Über die Basisfunktionen von I18N hinaus, wie das Bereitstellen von verschiedenen Eingabecodierungen oder die diversen nationalen Konventionen, zum Beispiel die verschiedenen Dezimalpunkte, ist es auf einem höheren Level von I18N möglich, die Ausgabe von Programmen zu lokalisieren. Ein Weg dies zu tun besteht in der Nutzung der POSIX.1 NLS-Funktionen von FreeBSD.
POSIX.1 NLS basiert auf Katalogdateien, welche die lokalisierten Mitteilungen in der entsprechenden Codierung enthalten. Die Mitteilungen sind in Sets organisiert und jede Mitteilung ist durch eine eindeutige Zahl in dem jeweiligen Set identifiziert. Die Katalogdateien werden nach der Lokale, von den jeweiligen lokalisierten Mitteilungen, die sie enthalten, gefolgt von der .msg Endung benannt. Zum Beispiel werden die ungarischen Mitteilungen für das ISO8859-2 Encoding in einer Datei mit dem Dateinamen hu_HU.ISO8859-2 gespeichert.
Diese Katalogdateien sind normale Textdateien, welche die nummerierten Mitteilungen enthalten. Es ist möglich Kommentare in die Dateien zu schreiben, indem Sie ein $-Zeichen an den Anfang der Zeile setzen. Das Setzen von Grenzen wird ebenfalls durch spezielle Kommentare möglich wobei das Schlüsselwort set direkt nach dem $-Zeichen folgen muss. Dem Schlüsselwort set folgt dann die Set-Nummer. Ein Beispiel:
$set 1
Der aktuelle Mitteilungseintrag startet mit der Mitteilungsnummer gefolgt von der lokalisierten Nachricht. Die bekannten Modifikatoren von printf(3) werden akzeptiert:
15 "File not found: %s\n"
Die Katalogdateien müssen in binärer Form vorliegen, bevor sie von einem Programm benutzt werden können. Dies wird mit dem gencat(1) Tool durchgeführt. Das erste Argument ist der Dateiname des kompilierten Katalogs und die weiteren Argumente sind die Eingabekataloge. Die lokalisierten Mitteilungen können auf mehrere Katalogdateien aufgeteilt sein. Danach werden dann alle auf einmal mit dem gencat(1) Tool kompiliert.
Das Benutzen der Katalogdateien ist einfach. Um die relevante Funktion zu nutzen, muss nl_types.h in die Quelldatei eingefügt werden. Bevor ein Katalog benutzt werden kann, muss er mit catopen(3) geöffnet werden. Die Funktion hat 2 Argumente. Der erste Parameter ist der Name des installierten und kompilierten Katalogs. Normalerweise wird der Name des Programmes, zum Beispiel grep, genutzt. Dieser Name wird zum Suchen der kompilierten Katalogdatei benutzt. Der Aufruf von catopen(3) sucht nach dieser Datei in /usr/share/nls/locale/catname und in /usr/local/share/nls/locale/catname, wobei locale die gesetzte Lokale und catname der Katalogname ist. Der zweite Parameter ist eine Konstante, die zwei Werte haben kann:
NL_CAT_LOCALE, hat die Bedeutung, dass die benutzte Katalogdatei auf LC_MESSAGES basiert.
0, hat die Bedeutung, dass LANG benutzt wird, um die Katalogdatei zu öffnen.
Der catopen(3) Aufruf gibt einen Katalogidentifizierer vom Type nl_catd zurück. Sehen Sie in der Manualpage nach, um eine Liste mit möglichen Fehlercodes zu erhalten.
Nach dem Öffnen eines Katalogs, kann catgets(3) benutzt werden, um Mitteilungen zu erhalten. Der erste Parameter ist der Katalogidentifizierer, der von catopen(3) zurück gegeben wurde, das zweite ist die Nummer des Sets, das dritte die Nummer der Mitteilung und das vierte ist eine Fallbackmitteilung, die angezeigt wird, falls die gewünschte Mitteilung in der Katalogdatei nicht verfügbar ist.
Nach der Nutzung der Katalogdatei, muss sie mit dem Kommando catclose(3), geschlossen werden. Es besitzt ein Argument, die Katalog ID.
Das folgende Beispiel zeigt einen einfachen Weg wie man NLS-Kataloge flexibel nutzen kann.
Die nachfolgenden Zeilen müssen in eine allgemeine Headerdatei, die in allen Quelldateien vorhanden ist, die lokalisierte Mitteilungen benutzen, eingefügt werden:
#ifdef WITHOUT_NLS #define getstr(n) nlsstr[n] #else #include <nl_types.h> extern nl_catd catalog; #define getstr(n) catgets(catalog, 1, n, nlsstr[n]) #endif extern char *nlsstr[];
Als nächstes fügen Sie die folgenden Zeilen in den globalen Deklarationsteil der Hauptquelldatei ein:
#ifndef WITHOUT_NLS #include <nl_types.h> nl_catd catalog; #endif /* * Default messages to use when NLS is disabled or no catalog * is found. */ char *nlsstr[] = { "", /* 1*/ "some random message", /* 2*/ "some other message" };
Als nächstes kommt der Code der den Katalog öffnet, liest und schließt:
#ifndef WITHOUT_NLS catalog = catopen("myapp", NL_CAT_LOCALE); #endif ... printf(getstr(1)); ... #ifndef WITHOUT_NLS catclose(catalog); #endif
Es gibt einen guten Weg, Zeichenketten die lokaliesert werden müssen, durch den Einsatz von libc-Fehlermeldungen zu reduzieren. Dadurch vermeidet man Duplikate und erstellt gleiche Meldungen für häufige Fehlermeldungen, die bei vielen Programmen auftreten können.
Als erstes ist hier ein Beispiel, dass keine libc-Fehlermeldungen benutzt:
#include <err.h> ... if (!S_ISDIR(st.st_mode)) err(1, "argument is not a directory");
Dies kann so abgeändert werden, dass eine Fehlermeldung durch Auslesen der
Variabel errno
ausgegeben wird. Die Fehlermeldung wird
entsprechend dem Beispiel ausgegeben:
#include <err.h> #include <errno.h> ... if (!S_ISDIR(st.st_mode)) { errno = ENOTDIR; err(1, NULL); }
In diesem Beispiel wurde die benutzerdefinierte Zeichenkette entfernt.
Übersetzer haben weniger Arbeit, wenn sie ein Programm lokalisieren und die
Benutzer sehen die übliche “"Not a directory"” Fehlermeldung,
wenn dieser Fehler auftritt. Diese Meldung wird ihnen wahrscheinlich vertraut
erscheinen. Bitte beachten Sie, dass es notwendig ist, errno.h hinzuzufügen um einen direkten Zugriff auf
errno
zu haben.
Es lohnt sich darauf hinzuweisen, dass es Fälle gibt, in denen errno
automatisch aufgerufen wird, so dass es nicht
notwendig ist, es explizit zu tun:
#include <err.h> ... if ((p = malloc(size)) == NULL) err(1, NULL);
Das Benutzen von Katalogdateien setzt einige sich wiederholende Schritte, wie das kompilieren und installieren der Kataloge, voraus. Um diese Schritte zu vereinfachen, stellt bsd.nls.mk einige Makros zur Verfügung. Es ist nicht notwendig bsd.nls.mk explizit hinein zu kopieren, es wird automatisch aus den allgemeinen Makefiles wie bsd.prog.mk oder bsd.lib.mk gezogen.
Normalerweise reicht es, NLSNAME zu definieren, die den Namen des Kataloges als erstes Argument von catopen(3) enthalten sollte und die Katalogdateien in NLS ohne ihre Endung .msg auflistet. Hier ist ein Beispiel, das es ermöglicht, NLS mit dem obigen Code zu deaktivieren. Die WITHOUT_NLS Variable von make(1) muss so definiert werden, dass das Programm ohne NLS-Unterstützung gebaut wird.
.if !defined(WITHOUT_NLS) NLS= es_ES.ISO8859-1 NLS+= hu_HU.ISO8859-2 NLS+= pt_BR.ISO8859-1 .else CFLAGS+= -DWITHOUT_NLS .endif
Normalerweise werden die Katalogdateien in dem nls-Unterverzeichnis abgelegt. Dies ist der Standard von bsd.nls.mk. Es ist möglich, mit der NLSSRCDIR-Variablen von make(1) diese zu überschreiben. Der Standardname der vorkompilierten Katalogdateien folgt den Namenskonventionen, wie oben beschrieben. Er kann durch die NLSNAME-Variablen überschrieben werden. Es gibt noch weitere Optionen, um eine Feinabstimmung zur Verarbeitung der Katalogdateien zu erreichen. Da sie nicht notwendig sind, werden sie hier nicht weiter beschrieben. Weitere Informationen über bsd.nls.mk finden Sie in der Datei selbst. Der Text ist kurz und leicht zu verstehen.
Zurück | Zum Anfang | Weiter |
Lokalisierung und Internationalisierung - L10N und I18N | Nach oben | Vorgaben und Richtlinien für das Quelltextverzeichnis |
Wenn Sie Fragen zu FreeBSD haben, schicken Sie eine E-Mail an
<[email protected]>.
Wenn Sie Fragen zu dieser Dokumentation haben, schicken Sie eine E-Mail an <[email protected]>.