EVAL2

LIBRERIA <locale>


Introducción

Tradicionalmente, desarrollar aplicaciones para diversos mercados presentaba problemas de difícil solución. Por ejemplo: Inglés-americano; Inglés del Reino Unido; Francés; Español; Alemán, Etc. Cada cual utilizaba diversas técnicas para intentar mantener todas estas versiones con un mínimo de esfuerzo. Una de ellas consistía en mantener todos los mensajes y avisos textuales (ayudas, Etc.) en ficheros separados del fuente, de forma que (con ayuda de traductores profesionales) fuese fácil mantener versiones en los diversos lenguajes. Estas versiones eran compiladas según el caso mediante directivas condicionales de preproceso. Sin embargo, esto no era siempre factible, en especial en las rutinas de E/S formateadas.  Las pantallas ("Screens") de entrada/salida de datos y los listados de salida debían ser mantenidos en el fuente en diversas versiones que eran igualmente mantenidas mediante complicadas sentencias condicionales de preproceso.

Localismos del lenguaje:

Comprende el lenguaje natural utilizado (español, inglés, francés griego, Etc.) y el juego de caracteres que constituye su alfabeto, incluyendo los signos de puntuación.
Ejemplo:
Inglés americano:      a-z; A-Z; signos de puntuación
Alemán:                       a-z; A-Z; signos de puntuación; äöü ÄÖÜ ß
Griego:                       a-w; A-W; signos de puntuación

Localismos numéricos:

La representación de las cantidades numéricas depende de costumbres locales que varían de país en país. La más conocida es quizás la distinta forma de representar la fracción decimal de los números fraccionarios. En inglés americano se utiliza un punto . para separar la parte entera de la decimal, mientras que en la mayor parte de Europa se utiliza la coma , para este mismo fin [3]. Recíprocamente, en USA se utiliza la coma para separar los grupos de tres cifras de las magnitudes grandes (símbolo de separación de miles) y en Europa se utiliza el punto. Incluso la forma de agrupar las cifras es distinta en las diversas culturas.


Ejemplo:
USA:                   1,000,000,55
España:           1.000.000,55
Nepal:               10,00,000.55

Localismos de moneda:

Además de que el sistema monetario es distinto en los diversos países del mundo, también existen importantes diferencias en la forma en que son representadas las magnitudes monetarias, incluyendo el símbolo de la moneda y la representación de los valores negativos. Por ejemplo, existen dos formas de representar la misma cantidad de dólares USA:
USA:                $24.99 US
Resto de países del mundo:   24.99 USD
La posición del símbolo monetario puede estar al principio, al final, o incluso en medio del valor numérico:
Japón:  155
España [4] :     13,50 Pts.
Alemania [4]:  13,50 DM.
Reino Unido [5]:         #14 19s. 6d.

Localismos de fecha y hora:

Las formas de representación de fecha y hora varían grandemente entre los diversos grupos culturales. Algunos países o grupos utilizan un sistema horario de 24 horas, mientras otros utilizan el de 12. Por supuesto en cada lengua varían las abreviaturas utilizadas para meses y días de la semana, así como los símbolos utilizados para separarlas.                                                                                     A continuación se muestran diversos ejemplos de representación de la misma fecha en diferentes países.
USA:    10/29/96         Tuesday, October 29, 1996
Hungría:                          1996. 10. 29.          1996. oktöber 29.
Italia:                               29/10/96    martedì 29 ottobre 1996
Grecia:                                        29/10/1996            Trith, 29 Oktwbriou 1996
Alemania:                   29.10.96          Dienstag, 29. Oktober 1996
España:                       29-10-96         Martes 29 de Octubre de 1996

Localismos en C:

Tanto los programadores como los fabricantes de compiladores fueron rápidamente conscientes que sería de gran ayuda disponer  en el propio lenguaje de herramientas específicas que ayudaran a la internacionalización. La idea es que la información correspondiente a las diferencias locales fuese de algún modo accesible al programa, de forma que pudiera ser utilizada por las rutinas afectadas (principalmente de E/S) de la forma más automática posible. En respuesta a esta necesidad, el consorcio X/Open [8] estandarizó una serie de servicios que proporcionan un soporte de estas características en el lenguaje C. Estos servicios son conocidos como NLS ("Native Languaje Support") o XPG4.
De acuerdo con el XPG4 los localismos C están agrupados según su contenido en varias categorías, identificadas internamente mediante seis constantes manifiestas, que coinciden aproximadamente con las que hemos enunciado:
LC_NUMERIC               Reglas y símbolos para localismos numéricos.
LC_TIME                       Detalles y reglas para fecha y hora
LC_MONETARY          Reglas y símbolos para localismos de moneda.
LC_CTYPE                    Reglas de clasificación de caracteres y conversión mayúsculas/minúsculas
LC_COLLATE                 Reglas de ordenación
LC_MESSAGES           Formato y valor de los mensajes

Para el manejo de estas estructuras se han provisto dos nuevas funciones: localeconv() , y setlocale() para cargar los ficheros externos.  Es corriente referirse colectivamente a estos conjuntos de valores y reglas como un locale. Inicialmente el compilador proporciona unos valores por defecto a estos locales, pero se pueden cargar otros desde el fichero externo correspondiente mediante setlocale. A partir de su invocación, las reglas y criterios del nuevo locale quedan a disposición de las funciones que los necesiten.
La definición y reglas de uso de setlocale pueden ser consultadas en el manual de su compilador, pero adelantaremos aquí que no solo permite establecer nuevos valores para los localismos, también consultar los valores actuales. Su definición está en <locale.h> o <clocale>, y existe en dos versiones: una para caracteres normales y otra para caracteres anchos. La primera responde a la declaración:

char* setlocale(int category, const char* locale);

La función devuelve un puntero a carácter que señala el principio de una cadena identificativa del localismo. El argumento category es una constante manifiesta que permite definir que categoría se fija/consulta. Puede ser cualquiera de las señaladas en la tabla anterior  o LC_ALL que afecta a todas las categorías.  El argumento locale es un puntero a cadena de caracteres que identifica el locale que se desea cargar.  Este argumento acepta diversas formas:

"lang[_country[.code_page]]"        Establece el locale que se cargará
".code_page"                                    Establece la página de códigos que se debe cargar  
""                                                      Establece el localismo establecido por defecto para el SO.
NULL                                               Modo consulta: devuelve el localismo actualmente en uso                                                                      sin realizar ningún cambio.

Localismo nativo

En ocasiones el programador no impone un localismo específico, decidiendo que sea el usuario el que establezca el que desea. En estos casos puede utilizarse al principio del programa una invocación en la forma:
setlocale(LC_ALL, "");
Esta llamada establece el localismo establecido por defecto en el SO.

Funciones dependiente del localismo

De lo dicho anteriormente se desprende que un número de funciones de la Librería Estándar C adaptan automáticamente ciertos detalles de su funcionamiento de los valores del locale. Este tipo de código se denomina adaptativo y a título de ejemplo podemos citar las siguientes funciones:

Función                                              Tipo de información que maneja
isalpha(), isupper(), isdigit(), ...       Información sobre caracteres.
tolower(), toupper()                       Conversiones mayúsculas/minúsculas
atof(),  atoi(),  atol()                      Convertir cadenas de caracteres a valores numéricos
strftime(), ...                                      Fecha y hora
strfmon()                                          Monetaria
printf(), scanf(), ...                           Análisis y formateos numéricos
strcoll(), wcscoll(), ...                         Ordenación y comparación alfabéticas de cadenas
mblen(), mbtowc(), wctomb(), ...    Caracteres multibyte.
catopen(), catgets(), catclose()       Mensajes textuales.

El ejemplo que sigue ilustra el principio de funcionamiento y como el entorno local afecta el comportamiento de la función printf().

#include <locale.h>   // compilar como programa C #include <stdio.h>
float fl = 1.2345F;                                                                                                                           char* loc;
int main() {          // ================                                                                                                    loc = setlocale(LC_ALL, NULL);    // modo consulta
   printf("locale actual: %s\n", loc);
   printf("Valor de fl: %f\n", fl);
   loc = setlocale(LC_ALL, "");      // localismo nativo
   printf("locale actual:\n%s\n", loc);
   printf("Valor de fl: %f\n", fl);
   loc = setlocale(LC_ALL, "german"); // localismo específico (alemán)
   printf("locale actual:\n%s\n", loc);
   printf("Valor de fl: %f\n", fl);
   return 0;
}
Salida:
locale actual: C                                                                                                                                  Valor de fl: 1.234500                                                                                                              
       locale actual:
LC_MONETARY=Spanish_Spain.850                                                            LC_TIME=Spanish_Spain.850                                                         LC_NUMERIC=Spanish_Spain.850                                                  LC_COLLATE=Spanish_Spain.850                                                      LC_CTYPE=Spanish_Spain.850                                                                                                           Valor de fl: 1,234500
locale actual:
LC_MONETARY=German_Germany.850                                              LC_TIME=German_Germany.850                                             LC_NUMERIC=German_Germany.850                                        LC_COLLATE=German_Germany.850                                              LC_CTYPE=German_Germany.850                                                                                                      Valor de fl: 1,234500


Localismos en C++

Como veremos inmediatamente, el esquema C de tratamiento de localismos se mantiene en C++ por compatibilidad (las definiciones correspondientes al fichero clásico <locale.h> han sido trasladadas a <clocale>), pero este lenguaje ofrece un tratamiento particular y específico del problema de la internacionalización, mucho más potente y versátil que su contrapartida C, pero también mucho más complejo y sofisticado.
Los localismos C++ ofrecen servicios similares a los de C, aunque los mecanismos involucrados difieren. Por ejemplo, los localismos C son recursos globales, y hemos señalado que solo puede existir un localismo para toda la aplicación; en consecuencia, es difícil conseguir que pueda atender simultáneamente a diversos localismos. En cambio, como el localismo C++ está definido en una clase, pueden instanciarse diversos objetos que pueden coexistir y cada uno puede servir a una convención cultural específica.
























No hay comentarios:

Publicar un comentario