gettext işlevlerinin büyük sorunlara yol açtığı kullanım yerlerinden biri görsel arayüzlü (GUI) yazılımlardır. Burada sorun çevrilecek iletilerin çoğunun çok kısa olması gerekliliğinden kaynaklanır. Bunlara genellikle menülerde rastlanır. Bu dizgeler tam bir cümle içeremedikleri gibi bir dilde aynı olan dizgelerin diğer dillerde farklı olabilmesi sorun oluşturur. Bu tek sözcüklük dizgelerde iyice belirginleşir.
Çoğu kimse, gettext yaklaşımı yerine bu sorunun görülmediği catgets işlevlerinin kullanılması gerektiğini söyler. Ancak, bu sorunları gettext işlevleri kullanıldığında aşmanın çok basit ve oldukça güçlü bir yöntemi vardır.
Görsel arayüzlü bir yazılımın şöyle bir menüsü olduğunu varsayalım:
+------------+------------+--------------------------------------+
| File | Printer | |
+------------+------------+--------------------------------------+
| Open | | Select |
| New | | Open |
+----------+ | Connect |
+----------+
Kodun bazı yerlerinde gettext ailesinden işlevlerde File, Printer, Open, New, Select ve Connect dizgelerinin çevirilerine erişildiğini varsayalım. Ancak dikkat ederseniz iki yerde işleve aktarılan dizge Open olacaktır. Yukarıda açıklanan açmazdan dolayı bu dizgenin çevirileri aynı olmayabilecektir.
Bu sorunun çözümlerinden biri belirsizliği ortadan kaldırmak için dizgeyi yapay olarak uzatmak ama çevirmenden sadece asıl dizgeyi çevirmesini istemektir. Fakat bir çeviri bulunamadığında yazılım ne yapacak? Uzatılan dizge basılamaz. O halde işlevin biraz değiştirilmiş bir sürümünü kullanmamız gerekir.
Dizgenin uzatılmasında tektip bir yönteme ihtiyaç vardır. Örneğin, yukarıdaki örnek için uzatılmış dizgeler şöyle seçilebilir:
Menu|File
Menu|Printer
Menu|File|Open
Menu|File|New
Menu|Printer|Select
Menu|Printer|Open
Menu|Printer|Connect
Böylece dizgelerin hepsi farklı oldu. Eğer gettext işlevini aşağıdaki işlevle kullanırsak herşey istendiği gibi olacaktır:
char *
sgettext (const char *msgid)
{
char *msgval = gettext (msgid);
if (msgval == msgid)
msgval = strrchr (msgid, '|') + 1;
return msgval;
}
Bu küçük işlevin tek yaptığı bir çevirinin bulunmadığı zaman uzatılmış dizgeden özgün dizgeyi elde etmektir. Dönen değer girdi değeri olduğundan bu işlem doğrudan bir gösterici karşılaştırması olarak yapıldığında daha verimli olur. Bir çevirinin bulunmaması halinde girdi dizgesinin | karakterini içereceğini bildiğimize göre dizge içinde bu karakterin son görüldüğü yeri bulup bu noktaya bir gösterici döndürmek yeterli olacaktır.
Eğer uzatılmış dizgeleri tutarlı şekilde kullanır ve gettext çağrılarını sgettext çağrıları ile değiştirirsek (bunu sadece görsel yazılımda gerektiği yerde yapmak yeterlidir), uluslarasılaştırılabilen bir yazılım üretebiliriz.
GNU C gibi ileri düzey derleyicilerle sgettext işlevi bir satıriçi işlev veya bunun gibi bir makro olarak gerçeklenebilir:
#define sgettext(msgid) \
({ const char *__msgid = (msgid); \
char *__msgstr = gettext (__msgid); \
if (__msgval == __msgid) \
__msgval = strrchr (__msgid, '|') + 1; \
__msgval; })
Diğer gettext işlevleri de (dgettext, dcgettext ve ngettext) benzer şekilde bir sarmalayıcı işlevle kullanılabilir.
Şimdi bir soru gelecek akıllara: GNU C kütüphanesinde neden böyle işlevler yok? Bu sorunun iki şıklı bir yanıtı var:
Yazılması kolaydır, bu bakımdan kullanıldıkları projenin içinde yazılabilirler. Bu bir yanıt değil derseniz, ikinci şık ile birlikte değerlendirildiğinde birşey ifade eder:
C kütüphanesinde heryerde çalışabilecek bir sürümün bulunmasını sağlayacak bir yöntem yok. Sorun, uzatılmış dizgede asıl dizgenin başına eklenen dizgeleri arasındaki karakterin seçiminden kaynaklanıyor. Yukarıdaki örnekte kullanılan | karakteri bu tür bağlamlarda sıkça kullanılan bir ayraç karakteri olarak iyi bir seçimdir ama ileti dizgelerinde de sık kullanılan bir karakterdir.
Eğer bu ayraç karakteri ileti dizgesinde de kullanılmışsa ne olacak? Ya da ayraç karakteri kodun derlendiği makinede yoksa ne olacak (örneğini ISO C için | karakteri gerekli değildir; bu nedenle ISO C yazılım geliştirme ortamında ayrıca bir iso646.h dosyası vardır).
Sadece bir açıklama daha kaldı. Yukarıdaki sarmalayıcı işlev uzatılmış dizgenin tamamının çevrilmeyeceği esasına dayandırılmıştır. Mantık bunu gerektirdiği için böyle yapılmıştır. Çeviri, arama için bir anahtar olarak kullanılmadığından neyi nasıl içerdiğinin bir önemi yoktur, hem gereksiz bellek harcamanın da alemi yok.