1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
|
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
The FreeBSD Documentation Project
The FreeBSD German Documentation Project
$FreeBSD$
$FreeBSDde: de-docproj/books/developers-handbook/l10n/chapter.xml,v 1.15 2010/12/15 19:03:51 bcr Exp $
basiert auf: 1.14
-->
<chapter id="l10n">
<chapterinfo>
<authorgroup>
<author>
<firstname>Jochen</firstname>
<surname>Neumeister</surname>
<contrib>Übersetzt von </contrib>
</author>
</authorgroup>
</chapterinfo>
<title>Lokalisierung und Internationalisierung - L10N und
I18N</title>
<sect1 id="l10n-programming">
<title>I18N-konforme Anwendungen programmieren</title>
<indexterm><primary>Qt</primary></indexterm>
<indexterm><primary>GTK</primary></indexterm>
<para>Um Ihre Anwendung verwendbarer für andere
Sprachen zu machen, hoffen wir, dass Sie I18N-konform
programmieren. Der GNU gcc-Compiler und Bibliotheken
für grafische Benutzeroberflächen wie QT und GTK
unterstützen I18N durch eine spezielle Verarbeitung von
Zeichenketten. Das Erstellen eines I18N-konformen Programms
ist sehr einfach und erlaubt anderen Mitwirkenden, Ihre
Programme leichter in andere Sprachen zu übersetzen.
Lesen Sie die Bibliothek-spezifischen I18N-Dokumentationen
für weitere Details.</para>
<para>Im Gegensatz zur allgemeinen Meinung ist I18N-konformer
Code einfach zu programmieren. Üblicherweise umfasst
dies nur das Einbetten Ihrer Zeichenketten in
Bibliothek-spezifische Funktionen. Stellen Sie außerdem
bitte sicher, dass Sie Unterstützung für Unicode- und
Multibyte-Zeichen vorsehen.</para>
<sect2>
<title>Ein Aufruf, die I18N-Bemühungen zu
vereinheitlichen</title>
<para>Wir sind darauf aufmerksam geworden, dass die
einzelnen I18N-/L10N-Bemühungen für jedes Land
wiederholt wurden. Viele von uns haben somit unproduktiverweise
das Rad immer wieder neu erfunden. Wir hoffen, dass die
verschiedenen großen Gruppen für I18N Ihre
Bemühungen in einer Gruppe vereinen können,
ähnlich der Zuständigkeit des Core-Teams.</para>
<para>Derzeit hoffen wir, dass wenn Sie I18N-konforme
Programme schreiben oder portieren, diese an die
betreffenden FreeBSD-Mailinglisten jedes Landes schicken, um
sie testen zu lassen. Wir hoffen in Zukunft, Anwendungen zu
entwickeln, die in allen Sprachen direkt und ohne unsaubere
Änderungen funktionieren.</para>
<para>Die &a.i18n;-Mailingliste ist eingerichtet worden. Wenn
Sie I18N-/L10N-Entwickler sind, schicken Sie bitte Ihre
Kommentare, Ideen, Fragen und alles, das Sie mit dem Thema in
Verbindung bringen, dorthin.</para>
</sect2>
<sect2>
<title>Perl und Python</title>
<indexterm>
<primary>Perl</primary>
</indexterm>
<indexterm>
<primary>Python</primary>
</indexterm>
<para>Perl und Python bieten Bibliotheken für I18N und zur
Behandlung von Unicode-Zeichen. Bitte nutzen Sie diese
für I18N-Konformität.</para>
</sect2>
</sect1>
<sect1 id="posix-nls">
<sect1info>
<authorgroup>
<author>
<firstname>Gábor</firstname>
<surname>Kövesdán</surname>
<contrib>Beigetragen von </contrib>
</author>
</authorgroup>
</sect1info>
<title>Lokalisierte Nachrichten mit POSIX.1 Native Language
Support (NLS)</title>
<para>Ü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 &os;.</para>
<sect2 id="nls-catalogs">
<title>Organisation von lokalisierten Mitteilungen in Katalog
Dateien</title>
<para>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
<literal>.msg</literal> Endung benannt. Zum Beispiel werden die
ungarischen Mitteilungen für das ISO8859-2 Encoding in
einer Datei mit dem Dateinamen <filename>hu_HU.ISO8859-2</filename>
gespeichert.</para>
<para>Diese Katalogdateien sind normale Textdateien, welche die
nummerierten Mitteilungen enthalten. Es ist möglich
Kommentare in die Dateien zu schreiben, indem Sie ein
<literal>$</literal>-Zeichen an den Anfang der Zeile setzen.
Das Setzen von Grenzen wird ebenfalls durch spezielle Kommentare
möglich wobei das Schlüsselwort <literal>set</literal>
direkt nach dem <literal>$</literal>-Zeichen folgen muss. Dem
Schlüsselwort <literal>set</literal> folgt dann die Set-Nummer.
Ein Beispiel:</para>
<programlisting>$set 1</programlisting>
<para>Der aktuelle Mitteilungseintrag startet mit der
Mitteilungsnummer gefolgt von der lokalisierten Nachricht. Die
bekannten Modifikatoren von &man.printf.3; werden akzeptiert:</para>
<programlisting>15 "File not found: %s\n"</programlisting>
<para>Die Katalogdateien müssen in binärer Form vorliegen,
bevor sie von einem Programm benutzt werden können. Dies wird
mit dem &man.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 &man.gencat.1;
Tool kompiliert.</para>
</sect2>
<sect2 id="nls-using">
<title>Nutzung der Katalogdateien im Quellcode</title>
<para>Das Benutzen der Katalogdateien ist einfach. Um die
relevante Funktion zu nutzen, muss <filename
class="headerfile">nl_types.h</filename> in die Quelldatei
eingefügt werden. Bevor ein Katalog benutzt werden
kann, muss er mit &man.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
<application>grep</application>, genutzt. Dieser Name wird
zum Suchen der kompilierten Katalogdatei benutzt. Der Aufruf
von &man.catopen.3; sucht nach dieser Datei in <filename
class="directory">/usr/share/nls/<replaceable>locale</replaceable>/<replaceable>catname</replaceable></filename>
und in <filename
class="directory">/usr/local/share/nls/<replaceable>locale</replaceable>/<replaceable>catname</replaceable></filename>,
wobei <literal>locale</literal> die gesetzte Lokale und
<literal>catname</literal> der Katalogname ist. Der zweite
Parameter ist eine Konstante, die zwei Werte haben kann:</para>
<itemizedlist>
<listitem>
<para><literal>NL_CAT_LOCALE</literal>, hat die Bedeutung,
dass die benutzte Katalogdatei auf
<envar>LC_MESSAGES</envar> basiert.</para>
</listitem>
<listitem>
<para><literal>0</literal>, hat die Bedeutung, dass
<envar>LANG</envar> benutzt wird, um die Katalogdatei
zu öffnen.
</para>
</listitem>
</itemizedlist>
<para>Der &man.catopen.3; Aufruf gibt einen Katalogidentifizierer
vom Type <literal>nl_catd</literal> zurück. Sehen Sie in der
Manualpage nach, um eine Liste mit möglichen Fehlercodes
zu erhalten.</para>
<para>Nach dem Öffnen eines Katalogs, kann &man.catgets.3;
benutzt werden, um Mitteilungen zu erhalten. Der erste
Parameter ist der Katalogidentifizierer, der von
&man.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.</para>
<para>Nach der Nutzung der Katalogdatei, muss sie mit dem
Kommando &man.catclose.3;, geschlossen werden. Es besitzt
ein Argument, die Katalog ID.</para>
</sect2>
<sect2 id="nls-example">
<title>Ein Beispiel aus der Praxis</title>
<para>Das folgende Beispiel zeigt einen einfachen Weg wie man
NLS-Kataloge flexibel nutzen kann.</para>
<para>Die nachfolgenden Zeilen müssen in eine allgemeine
Headerdatei, die in allen Quelldateien vorhanden ist, die
lokalisierte Mitteilungen benutzen, eingefügt werden:</para>
<programlisting>
#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[];
</programlisting>
<para>Als nächstes fügen Sie die folgenden Zeilen
in den globalen Deklarationsteil der Hauptquelldatei ein:</para>
<programlisting>
#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"
};
</programlisting>
<para>Als nächstes kommt der Code der den Katalog
öffnet, liest und schließt:</para>
<programlisting>
#ifndef WITHOUT_NLS
catalog = catopen("myapp", NL_CAT_LOCALE);
#endif
...
printf(getstr(1));
...
#ifndef WITHOUT_NLS
catclose(catalog);
#endif
</programlisting>
<sect3>
<title>Reduzierung von zu lokalisierenden Zeichenketten</title>
<para>Es gibt einen guten Weg, Zeichenketten die lokaliesert
werden müssen, durch den Einsatz von
<application>libc</application>-Fehlermeldungen zu reduzieren.
Dadurch vermeidet man Duplikate und erstellt gleiche Meldungen
für häufige Fehlermeldungen, die bei vielen
Programmen auftreten können.</para>
<para>Als erstes ist hier ein Beispiel, dass keine
<application>libc</application>-Fehlermeldungen benutzt:</para>
<programlisting>
#include <err.h>
...
if (!S_ISDIR(st.st_mode))
err(1, "argument is not a directory");
</programlisting>
<para>Dies kann so abgeändert werden, dass eine
Fehlermeldung durch Auslesen der Variabel <varname>errno</varname>
ausgegeben wird. Die Fehlermeldung wird entsprechend dem Beispiel
ausgegeben:</para>
<programlisting>
#include <err.h>
#include <errno.h>
...
if (!S_ISDIR(st.st_mode)) {
errno = ENOTDIR;
err(1, NULL);
}
</programlisting>
<para>In diesem Beispiel wurde die benutzerdefinierte
Zeichenkette entfernt. Übersetzer haben weniger Arbeit,
wenn sie ein Programm lokalisieren und die Benutzer sehen die
übliche <quote>"Not a directory"</quote>
Fehlermeldung, wenn dieser Fehler auftritt. Diese Meldung wird
ihnen wahrscheinlich vertraut erscheinen. Bitte beachten Sie,
dass es notwendig ist,
<filename class="headerfile">errno.h</filename>
hinzuzufügen um einen direkten Zugriff auf
<varname>errno</varname> zu haben.</para>
<para>Es lohnt sich darauf hinzuweisen, dass es Fälle gibt,
in denen <varname>errno</varname> automatisch aufgerufen wird,
so dass es nicht notwendig ist, es explizit zu tun:</para>
<programlisting>
#include <err.h>
...
if ((p = malloc(size)) == NULL)
err(1, NULL);
</programlisting>
</sect3>
</sect2>
<sect2 id="nls-mk">
<title>Benutzung von <filename>bsd.nls.mk</filename></title>
<para>Das Benutzen von Katalogdateien setzt einige sich
wiederholende Schritte, wie das kompilieren und installieren
der Kataloge, voraus. Um diese Schritte zu vereinfachen,
stellt <filename>bsd.nls.mk</filename> einige Makros zur
Verfügung. Es ist nicht notwendig
<filename>bsd.nls.mk</filename> explizit hinein zu kopieren,
es wird automatisch aus den allgemeinen Makefiles wie
<filename>bsd.prog.mk</filename> oder
<filename>bsd.lib.mk</filename> gezogen.</para>
<para>Normalerweise reicht es, <makevar>NLSNAME</makevar> zu
definieren, die den Namen des Kataloges als erstes
Argument von &man.catopen.3; enthalten sollte und die
Katalogdateien in <makevar>NLS</makevar> ohne ihre Endung
<literal>.msg</literal> auflistet. Hier ist ein Beispiel, das
es ermöglicht, NLS mit dem obigen Code zu deaktivieren.
Die <makevar>WITHOUT_NLS</makevar> Variable von &man.make.1;
muss so definiert werden, dass das Programm ohne
NLS-Unterstützung gebaut wird.</para>
<programlisting>
.if !defined(WITHOUT_NLS)
NLS= es_ES.ISO8859-1
NLS+= hu_HU.ISO8859-2
NLS+= pt_BR.ISO8859-1
.else
CFLAGS+= -DWITHOUT_NLS
.endif
</programlisting>
<para>Normalerweise werden die Katalogdateien in dem
<filename class="directory">nls</filename>-Unterverzeichnis
abgelegt. Dies ist der Standard von
<filename>bsd.nls.mk</filename>. Es ist möglich, mit der
<makevar>NLSSRCDIR</makevar>-Variablen von &man.make.1; diese zu
überschreiben. Der Standardname der vorkompilierten
Katalogdateien folgt den Namenskonventionen, wie oben beschrieben.
Er kann durch die <makevar>NLSNAME</makevar>-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
<filename>bsd.nls.mk</filename> finden Sie in der Datei selbst.
Der Text ist kurz und leicht zu verstehen.</para>
</sect2>
</sect1>
</chapter>
|