4.2. POSIX.1 DesteÄŸi ile YerelleÅŸtirilmiÅŸ mesajlar (NLS)

Contributed by Gábor Kövesdán.

Basit değişik karakter kodlama sistemlerini , değişik ondalık ayracı gibi ulusal özel kullanımları desteklemek gibi I18N fonksiyonlarının ötesinde ayrıca I18N'in yüksek seviyesinde , herhangi bir programın çıktılarını bile özelleştirmeniz mümkündür. Bunun için ortak olarak kullanılan yöntem POSIX.1 NLS fonksiyonlarıdır. Bunlar işletim sisteminin temel bir parçası olarak gelir.

4.2.1. Mesajları Katalog Dosyaları Şeklinde Tutmak

POSIX.1 NLS katalog dosyası tabanlıdır.Katalog dosyaları istenilen kodlama (encoding) biçimine göre yerelleştirilmiş mesajları tutar. Mesajlar kümeler şeklinde tutulur ve her mesaj bulunduğu kümede numaralandırılarak ayırt edilir. Katalog dosyaları hangi dilde olduğuna göre isimlendirilir. Mesela Macar (Hu) dilinde ISO8859-2 kodlamasında tutulan mesajlar hu_HU.ISO8859-2. dosyasında saklanacaktır.

Bu katalog dosyaları yazı dosyalarıdır ve numaralandırılmış mesajları içerir. Eğer bu dosyalara yorum yazmak istiyorsanız $ karakterini kullanarak yazabilirsiniz. Küme sınırları özel bir komut ile ayrılır , bu komut set komutudur. Bu komut $ karakterinden sonra kullanılmalıdır. Mesela birinci küme için :

$set 1

Gerçek mesaj girdileri mesaj numarası ve yerelleştirilmiş mesaj ile başlar. Printf'in parametreleri burada da kullanılabilir. Mesela:

15 "File not found: %s\n"

Bu dosyaların programlar tarafından çalıştırılabilmesi için ikilik halde derlenmesi gerekmektedir. Bu işlem gencat tarafından yapılır . İlk argüman olarak derlenmiş kataloğun dosya ismi diğer argümanları ise giriş kataloglarının isimleridir. Bu yerelleştirilmiş mesajlar birden fazla katalog dosyası şeklinde düzenlenip tek bir derleme ile kullanarak işlenebilir.

4.2.2. Katalog Dosyalarının Kaynak Kod İçerisinde Kullanılması

Katalog dosyalarını kullanmak kolaydır. nl_types.h dosyasını kaynak kodunuza ekleyerek işe başlamalısınız. Kataloğu kullanmadan önce . ile açmalısınız. Bu komut iki argüman alır. İlk parametre kurulmuş olan derlenmiş haldeki katalog dosyası ismi , genellikle hangi programın kullanılacağı grep bunu belirler. Bu isim katalog dosyasını aramak için kullanılacaktır. çağrısı şu dosyaların içine bakar /usr/share/nls/locale/catname ve /usr/local/share/nls/locale/catname, locale bir küme barındırır ve catname bahsi geçen isimdir. İkinci parametre ise sabit bir değerdir sadece iki değer alabilir :

çağrısı nl_catd tipinin katalog tanımlayıcısını döndürür. Eğer hata mesajları hakkında daha fazla bilgi edinmek istiyorsanız yardım sayfalarına bakabilirsiniz.

Katalog açıldıktan sonra mesajları almak için kullanılabilir. İlk parametre 'dan dönen sayı değeri ikincisi ise kaç küme üzerinde çalışılacağıdır. Üçüncü parametre ise kaç tane mesaj olacağı , dördüncüsü ise geri dönüş mesajıdır. Bu mesaj katalog dosyasından okunmama durumunda dönüş yapılacak değerdir.

Katalog dosyasını kullandıktan sonra komutu kullanılarak kapatılmalıdır. Sadece tek bir argüman alır oda katalog numarasıdır.

4.2.3. Örnek

Örnekte NLS kataloglarının nasıl kullanıldığı hakkında basit bir çözüm gösterilmiştir.

Aşağıdaki satırlar ortak .h dosyasına konulmalıdır. Bu sayede bütün yerelleştirme gereken kaynak kodu dosyaları bunu içermelidir (include).

#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[];

Sonra aşağıdaki satırları global alana ana kaynak kodu dosyasına yerleştirin.

#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"
};

Sonra açma , okuma , yazma için aşağıdaki kod örneklerini inceleyin.

#ifndef WITHOUT_NLS
	catalog = catopen("myapp", NL_CAT_LOCALE);
#endif
...
printf(getstr(1));
...
#ifndef WITHOUT_NLS
	catclose(catalog);
#endif

4.2.3.1. Yerelleştirilecek Yazıları Azaltmak

Yerelleştirilecek yazıları azaltmanın en iyi yolu libc uygulamasının hata mesajlarını kullanmaktır. Bununla ortak olarak karşılaşılan hata mesajlarını tutarlı bir şekilde kullanarak ikilikleri önlemiş olursunuz

İlk olarak libc kod örneği:

#include <err.h>
...
if (!S_ISDIR(st.st_mode))
	err(1, "argument is not a directory");
	  

Bu kod errno dan okuyarak bunun ekrana yazılması şeklinde değiştirilebilir.

#include <err.h>
#include <errno.h>
...
if (!S_ISDIR(st.st_mode)) {
	errno = ENOTDIR;
	err(1, NULL);
}
	  

Bu örnekte, özel yazı gerekmedi , bu yüzden çevirenler daha kolay çevirme yapabileceklerdir. Kullanıcılar standart hata mesajları alacaklar ve bu mesajlara daha aşina olacaklar. Burada unutmamanız gereken bir nokta errno değişkenine ulaşmak için errno.h dosyasını eklemeyi unutmamalısınız.

errno değişkeni bir önceki çağrı tarafından ayarlanmıştır dışarıdan tekrar ayar yapılmasına gerek yoktur.

#include <err.h>
...
if ((p = malloc(size)) == NULL)
	err(1, NULL);
	  

4.2.4. bsd.nls.mk Kullanımı

Katalog dosyaları kullanımı bazı tekrarlanan işlemleri de beraberinde getirecektir. Bunların derlenmesi , kurulumu işlemlerini otomatik hale getirmek için bsd.nls.mk dosyasını kullanmalısınız. Bu dosyayı ekstradan eklemeden bsd.prog.mk yada bsd.lib.mk gibi ortak Makefile dosyaları ile birlikte kullanabilirsiniz.

Genellikle NLSNAME değişkenini ayarlamanız komutunun ilk argümanını tanımlamak için yeterlidir. Sonra NLS değişkeni içerisine katalog dosyalarını .msg uzantısı olmadan sıralamalısınız. Aşağıdaki örnekte NLS ' yi iptal etme imkanı sağlayan bir kod verilmiştir.

.if !defined(WITHOUT_NLS)
NLS=	es_ES.ISO8859-1
NLS+=	hu_HU.ISO8859-2
NLS+=	pt_BR.ISO8859-1
.else
CFLAGS+=	-DWITHOUT_NLS
.endif

Genel kullanım katalog dosyalarını nls dizinine yerleştirmektir. Bu aynı zamanda bsd.nls.mk dosyasının varsayılan davranışıdır. Fakat isterseniz dizini değiştirmek için NLSSRCDIR değişkenini kullanabilirsiniz. Diğer seçenekler daha ince ayar için kullanılabilir fakat zorunlu değildir. Daha detaylı bilgi için makefile dosyasının kendisine bakabilirsiniz. Kısa ve anlaşılır biçimde kullanım bu dosyada tarif edilmiştir.