summaryrefslogtreecommitdiff
path: root/app/wlib/mswlib/simple-gettext.c
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2024-07-03 10:19:36 +0200
committerJörg Frings-Fürst <debian@jff-webhosting.net>2024-07-03 10:19:36 +0200
commitb6bd52cd7330a90fc0e44dbe6022551a8dd768a1 (patch)
tree9804282102f8c40d27407b9c94119b35eeb5013c /app/wlib/mswlib/simple-gettext.c
parentc9d0740841fbe0539e42e66d3865672bfcd3ac02 (diff)
parenta14a7a0ccc9de76aeab0b2e4bbf58f1a79deedc2 (diff)
Update upstream source from tag 'upstream/5.3.0GA'
Update to upstream version '5.3.0GA' with Debian dir dfd14d63b0238e276ade6f54dd9100325df5b2f9
Diffstat (limited to 'app/wlib/mswlib/simple-gettext.c')
-rw-r--r--app/wlib/mswlib/simple-gettext.c600
1 files changed, 302 insertions, 298 deletions
diff --git a/app/wlib/mswlib/simple-gettext.c b/app/wlib/mswlib/simple-gettext.c
index 951ce4c..592e3a3 100644
--- a/app/wlib/mswlib/simple-gettext.c
+++ b/app/wlib/mswlib/simple-gettext.c
@@ -1,4 +1,4 @@
-/* \file simple-gettext.c
+/* \file simple-gettext.c
* a simplified version of gettext.
* Copyright (C) 1995, 1996, 1997, 1999,
* 2005 Free Software Foundation, Inc.
@@ -17,7 +17,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* This is a simplified version of gettext written by Ulrich Drepper.
@@ -28,8 +28,8 @@
*/
/*
- * Based on the simple-gettext from GnuPG a version appropriate for the
- * needs of XTrackCAD was derived. This is a workaround for any compiler
+ * Based on the simple-gettext from GnuPG a version appropriate for the
+ * needs of XTrackCAD was derived. This is a workaround for any compiler
* specifics or runtime library dependencies. mf 26.07.09
*/
@@ -50,10 +50,10 @@
#include "mswint.h"
#if _MSC_VER > 1300
- #define stricmp _stricmp
- #define strnicmp _strnicmp
- #define strdup _strdup
- #define fileno _fileno
+#define stricmp _stricmp
+#define strnicmp _strnicmp
+#define strdup _strdup
+#define fileno _fileno
#endif
typedef unsigned long u32;
@@ -67,60 +67,56 @@ typedef unsigned long u32;
/* Header for binary .mo file format. */
-struct mo_file_header
-{
- /* The magic number. */
- u32 magic;
- /* The revision number of the file format. */
- u32 revision;
- /* The number of strings pairs. */
- u32 nstrings;
- /* Offset of table with start offsets of original strings. */
- u32 orig_tab_offset;
- /* Offset of table with start offsets of translation strings. */
- u32 trans_tab_offset;
- /* Size of hashing table. */
- u32 hash_tab_size;
- /* Offset of first hashing entry. */
- u32 hash_tab_offset;
+struct mo_file_header {
+ /* The magic number. */
+ u32 magic;
+ /* The revision number of the file format. */
+ u32 revision;
+ /* The number of strings pairs. */
+ u32 nstrings;
+ /* Offset of table with start offsets of original strings. */
+ u32 orig_tab_offset;
+ /* Offset of table with start offsets of translation strings. */
+ u32 trans_tab_offset;
+ /* Size of hashing table. */
+ u32 hash_tab_size;
+ /* Offset of first hashing entry. */
+ u32 hash_tab_offset;
};
-struct string_desc
-{
- /* Length of addressed string. */
- u32 length;
- /* Offset of string in file. */
- u32 offset;
+struct string_desc {
+ /* Length of addressed string. */
+ u32 length;
+ /* Offset of string in file. */
+ u32 offset;
};
-struct overflow_space_s
-{
- struct overflow_space_s *next;
- u32 idx;
- char d[1];
+struct overflow_space_s {
+ struct overflow_space_s *next;
+ u32 idx;
+ char d[1];
};
-struct loaded_domain
-{
- char *data;
- int must_swap;
- u32 nstrings;
- char *mapped; /* 0 = not yet mapped, 1 = mapped,
+struct loaded_domain {
+ char *data;
+ int must_swap;
+ u32 nstrings;
+ char *mapped; /* 0 = not yet mapped, 1 = mapped,
2 = mapped to
overflow space */
- struct overflow_space_s *overflow_space;
- struct string_desc *orig_tab;
- struct string_desc *trans_tab;
- u32 hash_size;
- u32 *hash_tab;
+ struct overflow_space_s *overflow_space;
+ struct string_desc *orig_tab;
+ struct string_desc *trans_tab;
+ u32 hash_size;
+ u32 *hash_tab;
};
static struct loaded_domain *the_domain;
/**
* Translate the input string from UTF8 to Windows codepage.
- *
+ *
* \param str IN string in UTF-8 format to translate.
* \param len IN number of chars to translate
* \param dummy IN ?
@@ -129,7 +125,7 @@ static struct loaded_domain *the_domain;
char *
utf8_to_native( char *str, unsigned int len, int dummy )
{
- /* maximum output length is size of string * 2 */
+ /* maximum output length is size of string * 2 */
int buflen = (len + 1) * 2;
char *buf = malloc( buflen );
int wcharLen;
@@ -143,22 +139,24 @@ utf8_to_native( char *str, unsigned int len, int dummy )
/* the system codepage, we need to take two steps */
/* 1. convert from UTF-8 to UTF-16 */
- wcharLen = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)str, -1, (LPWSTR)buf, buflen / 2 );
-
+ wcharLen = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)str, -1, (LPWSTR)buf,
+ buflen / 2 );
+
/* 2. convert from UTF-8 to system codepage */
- WideCharToMultiByte(CP_ACP, 0, (LPWSTR)buf, wcharLen, resBuffer, len + 1, NULL, NULL );
+ WideCharToMultiByte(CP_ACP, 0, (LPWSTR)buf, wcharLen, resBuffer, len + 1, NULL,
+ NULL );
}
free(buf);
- return( resBuffer );
+ return( resBuffer );
}
static u32
do_swap_u32( u32 i )
{
- return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);
+ return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);
}
#define SWAPIT(flag, data) ((flag) ? do_swap_u32(data) : (data) )
@@ -174,205 +172,203 @@ do_swap_u32( u32 i )
static unsigned long
hash_string( const char *str_param )
{
- unsigned long int hval, g;
- const char *str = str_param;
-
- hval = 0;
- while (*str != '\0')
- {
- hval <<= 4;
- hval += (unsigned long int) *str++;
- g = hval & ((unsigned long int) 0xf << (HASHWORDBITS - 4));
- if (g != 0)
- {
- hval ^= g >> (HASHWORDBITS - 8);
- hval ^= g;
+ unsigned long int hval, g;
+ const char *str = str_param;
+
+ hval = 0;
+ while (*str != '\0') {
+ hval <<= 4;
+ hval += (unsigned long int) *str++;
+ g = hval & ((unsigned long int) 0xf << (HASHWORDBITS - 4));
+ if (g != 0) {
+ hval ^= g >> (HASHWORDBITS - 8);
+ hval ^= g;
+ }
}
- }
- return hval;
+ return hval;
}
static struct loaded_domain *
load_domain( const char *filename )
{
- FILE *fp;
- size_t size;
- struct stat st;
- struct mo_file_header *data = NULL;
- struct loaded_domain *domain = NULL;
- size_t to_read;
- char *read_ptr;
-
- fp = fopen( filename, "rb" );
- if( !fp )
- return NULL; /* can't open the file */
- /* we must know about the size of the file */
- if( fstat( fileno(fp ), &st )
- || (size = (size_t)st.st_size) != st.st_size
- || size < sizeof (struct mo_file_header) ) {
- fclose( fp );
- return NULL;
- }
-
- data = malloc( size );
- if( !data ) {
- fclose( fp );
- return NULL; /* out of memory */
- }
-
- to_read = size;
- read_ptr = (char *) data;
- do {
- unsigned long int nb = (unsigned int)fread( read_ptr, 1, to_read, fp );
- if( nb < to_read ) {
- fclose (fp);
- free(data);
- return NULL; /* read error */
+ FILE *fp;
+ size_t size;
+ struct stat st;
+ struct mo_file_header *data = NULL;
+ struct loaded_domain *domain = NULL;
+ size_t to_read;
+ char *read_ptr;
+
+ fp = fopen( filename, "rb" );
+ if( !fp ) {
+ return NULL; /* can't open the file */
}
- read_ptr += nb;
- to_read -= nb;
- } while( to_read > 0 );
- fclose (fp);
-
- /* Using the magic number we can test whether it really is a message
- * catalog file. */
- if( data->magic != MAGIC && data->magic != MAGIC_SWAPPED ) {
- /* The magic number is wrong: not a message catalog file. */
- free( data );
- return NULL;
- }
-
- domain = calloc( 1, sizeof *domain );
- if( !domain ) {
- free( data );
- return NULL;
- }
- domain->data = (char *) data;
- domain->must_swap = data->magic != MAGIC;
-
- /* Fill in the information about the available tables. */
- switch( SWAPIT(domain->must_swap, data->revision) ) {
- case 0:
- domain->nstrings = SWAPIT(domain->must_swap, data->nstrings);
- domain->orig_tab = (struct string_desc *)
- ((char *) data + SWAPIT(domain->must_swap, data->orig_tab_offset));
- domain->trans_tab = (struct string_desc *)
- ((char *) data + SWAPIT(domain->must_swap, data->trans_tab_offset));
- domain->hash_size = SWAPIT(domain->must_swap, data->hash_tab_size);
- domain->hash_tab = (u32 *)
- ((char *) data + SWAPIT(domain->must_swap, data->hash_tab_offset));
- break;
-
- default: /* This is an invalid revision. */
- free( data );
- free( domain );
- return NULL;
- }
-
- /* Allocate an array to keep track of code page mappings. */
- domain->mapped = calloc( 1, domain->nstrings );
- if( !domain->mapped ) {
- free( data );
- free( domain );
- return NULL;
- }
-
- return domain;
+ /* we must know about the size of the file */
+ if( fstat( fileno(fp ), &st )
+ || (size = (size_t)st.st_size) != st.st_size
+ || size < sizeof (struct mo_file_header) ) {
+ fclose( fp );
+ return NULL;
+ }
+
+ data = malloc( size );
+ if( !data ) {
+ fclose( fp );
+ return NULL; /* out of memory */
+ }
+
+ to_read = size;
+ read_ptr = (char *) data;
+ do {
+ unsigned long int nb = (unsigned int)fread( read_ptr, 1, to_read, fp );
+ if( nb < to_read ) {
+ fclose (fp);
+ free(data);
+ return NULL; /* read error */
+ }
+ read_ptr += nb;
+ to_read -= nb;
+ } while( to_read > 0 );
+ fclose (fp);
+
+ /* Using the magic number we can test whether it really is a message
+ * catalog file. */
+ if( data->magic != MAGIC && data->magic != MAGIC_SWAPPED ) {
+ /* The magic number is wrong: not a message catalog file. */
+ free( data );
+ return NULL;
+ }
+
+ domain = calloc( 1, sizeof *domain );
+ if( !domain ) {
+ free( data );
+ return NULL;
+ }
+ domain->data = (char *) data;
+ domain->must_swap = data->magic != MAGIC;
+
+ /* Fill in the information about the available tables. */
+ switch( SWAPIT(domain->must_swap, data->revision) ) {
+ case 0:
+ domain->nstrings = SWAPIT(domain->must_swap, data->nstrings);
+ domain->orig_tab = (struct string_desc *)
+ ((char *) data + SWAPIT(domain->must_swap, data->orig_tab_offset));
+ domain->trans_tab = (struct string_desc *)
+ ((char *) data + SWAPIT(domain->must_swap, data->trans_tab_offset));
+ domain->hash_size = SWAPIT(domain->must_swap, data->hash_tab_size);
+ domain->hash_tab = (u32 *)
+ ((char *) data + SWAPIT(domain->must_swap, data->hash_tab_offset));
+ break;
+
+ default: /* This is an invalid revision. */
+ free( data );
+ free( domain );
+ return NULL;
+ }
+
+ /* Allocate an array to keep track of code page mappings. */
+ domain->mapped = calloc( 1, domain->nstrings );
+ if( !domain->mapped ) {
+ free( data );
+ free( domain );
+ return NULL;
+ }
+
+ return domain;
}
/**
* Set the file used for translations. Pass a NULL to disable
- * translation. A new filename may be set at anytime. WARNING:
- * After changing the filename you should not access any data
+ * translation. A new filename may be set at anytime. WARNING:
+ * After changing the filename you should not access any data
* retrieved by gettext().
*/
int
set_gettext_file ( const char *filename, const char *regkey )
{
- struct loaded_domain *domain = NULL;
-
- if( filename && *filename ) {
- if( filename[0] == '/'
- || ( isalpha(filename[0])
- && filename[1] == ':'
- && (filename[2] == '/' || filename[2] == '\\') )
- ) {
- /* absolute path - use it as is */
- domain = load_domain( filename );
+ struct loaded_domain *domain = NULL;
+
+ if( filename && *filename ) {
+ if( filename[0] == '/'
+ || ( isalpha(filename[0])
+ && filename[1] == ':'
+ && (filename[2] == '/' || filename[2] == '\\') )
+ ) {
+ /* absolute path - use it as is */
+ domain = load_domain( filename );
+ }
+ if (!domain) {
+ return -1;
+ }
+ }
+
+ if( the_domain ) {
+ struct overflow_space_s *os, *os2;
+ free( the_domain->data );
+ free( the_domain->mapped );
+ for (os=the_domain->overflow_space; os; os = os2) {
+ os2 = os->next;
+ free (os);
+ }
+ free( the_domain );
+ the_domain = NULL;
}
- if (!domain)
- return -1;
- }
-
- if( the_domain ) {
- struct overflow_space_s *os, *os2;
- free( the_domain->data );
- free( the_domain->mapped );
- for (os=the_domain->overflow_space; os; os = os2) {
- os2 = os->next;
- free (os);
- }
- free( the_domain );
- the_domain = NULL;
- }
- the_domain = domain;
- return 0;
+ the_domain = domain;
+ return 0;
}
/**
- * Return the required string from the message table. Before returning the result,
+ * Return the required string from the message table. Before returning the result,
* codepage translation from UTF8 to current codepage is performed.
*/
static const char*
get_string( struct loaded_domain *domain, u32 idx )
{
- struct overflow_space_s *os;
- char *p;
-
- p = domain->data + SWAPIT(domain->must_swap, domain->trans_tab[idx].offset);
- if (!domain->mapped[idx])
- {
- size_t plen, buflen;
- char *buf;
-
- domain->mapped[idx] = 1;
-
- plen = strlen (p);
- buf = utf8_to_native (p, (unsigned int)plen, -1);
- buflen = strlen (buf);
- if (buflen <= plen){
- strcpy (p, buf);
- free( buf );
- } else {
- /* There is not enough space for the translation - store it
- in the overflow_space else and mark that in the mapped
- array. Because we expect that this won't happen too
- often, we use a simple linked list. */
- os = malloc (sizeof *os + buflen);
- if (os)
- {
- os->idx = idx;
- strcpy (os->d, buf);
- os->next = domain->overflow_space;
- domain->overflow_space = os;
- p = os->d;
- }
- else
- p = "ERROR in GETTEXT MALLOC";
- free (buf);
- }
- }
- else if (domain->mapped[idx] == 2)
- { /* We need to get the string from the overflow_space. */
- for (os=domain->overflow_space; os; os = os->next)
- if (os->idx == idx)
- return (const char*)os->d;
- p = "ERROR in GETTEXT\n";
- }
- return (const char*)p;
+ struct overflow_space_s *os;
+ char *p;
+
+ p = domain->data + SWAPIT(domain->must_swap, domain->trans_tab[idx].offset);
+ if (!domain->mapped[idx]) {
+ size_t plen, buflen;
+ char *buf;
+
+ domain->mapped[idx] = 1;
+
+ plen = strlen (p);
+ buf = utf8_to_native (p, (unsigned int)plen, -1);
+ buflen = strlen (buf);
+ if (buflen <= plen) {
+ strcpy (p, buf);
+ free( buf );
+ } else {
+ /* There is not enough space for the translation - store it
+ in the overflow_space else and mark that in the mapped
+ array. Because we expect that this won't happen too
+ often, we use a simple linked list. */
+ os = malloc (sizeof *os + buflen);
+ if (os) {
+ os->idx = idx;
+ strcpy (os->d, buf);
+ os->next = domain->overflow_space;
+ domain->overflow_space = os;
+ p = os->d;
+ } else {
+ p = "ERROR in GETTEXT MALLOC";
+ }
+ free (buf);
+ }
+ } else if (domain->mapped[idx] == 2) {
+ /* We need to get the string from the overflow_space. */
+ for (os=domain->overflow_space; os; os = os->next)
+ if (os->idx == idx) {
+ return (const char*)os->d;
+ }
+ p = "ERROR in GETTEXT\n";
+ }
+ return (const char*)p;
}
/**
@@ -382,78 +378,85 @@ get_string( struct loaded_domain *domain, u32 idx )
char *
gettext( const char *msgid )
{
- struct loaded_domain *domain;
- size_t act = 0;
- size_t top, bottom;
-
- if( !(domain = the_domain) )
- goto not_found;
-
- /* Locate the MSGID and its translation. */
- if( domain->hash_size > 2 && domain->hash_tab ) {
- /* Use the hashing table. */
- u32 len = (u32)strlen (msgid);
- u32 hash_val = hash_string (msgid);
- u32 idx = hash_val % domain->hash_size;
- u32 incr = 1 + (hash_val % (domain->hash_size - 2));
- u32 nstr = SWAPIT (domain->must_swap, domain->hash_tab[idx]);
-
- if ( !nstr ) /* Hash table entry is empty. */
- goto not_found;
-
- if( SWAPIT(domain->must_swap,
- domain->orig_tab[nstr - 1].length) == len
- && !strcmp( msgid,
- domain->data + SWAPIT(domain->must_swap,
- domain->orig_tab[nstr - 1].offset)) )
- return (char *)get_string( domain, nstr - 1 );
-
- for(;;) {
- if (idx >= domain->hash_size - incr)
- idx -= domain->hash_size - incr;
- else
- idx += incr;
-
- nstr = SWAPIT(domain->must_swap, domain->hash_tab[idx]);
- if( !nstr )
- goto not_found; /* Hash table entry is empty. */
-
- if ( SWAPIT(domain->must_swap,
- domain->orig_tab[nstr - 1].length) == len
- && !strcmp (msgid,
- domain->data + SWAPIT(domain->must_swap,
- domain->orig_tab[nstr - 1].offset)))
- return (char *)get_string( domain, nstr-1 );
+ struct loaded_domain *domain;
+ size_t act = 0;
+ size_t top, bottom;
+
+ if( !(domain = the_domain) ) {
+ goto not_found;
+ }
+
+ /* Locate the MSGID and its translation. */
+ if( domain->hash_size > 2 && domain->hash_tab ) {
+ /* Use the hashing table. */
+ u32 len = (u32)strlen (msgid);
+ u32 hash_val = hash_string (msgid);
+ u32 idx = hash_val % domain->hash_size;
+ u32 incr = 1 + (hash_val % (domain->hash_size - 2));
+ u32 nstr = SWAPIT (domain->must_swap, domain->hash_tab[idx]);
+
+ if ( !nstr ) { /* Hash table entry is empty. */
+ goto not_found;
+ }
+
+ if( SWAPIT(domain->must_swap,
+ domain->orig_tab[nstr - 1].length) == len
+ && !strcmp( msgid,
+ domain->data + SWAPIT(domain->must_swap,
+ domain->orig_tab[nstr - 1].offset)) ) {
+ return (char *)get_string( domain, nstr - 1 );
+ }
+
+ for(;;) {
+ if (idx >= domain->hash_size - incr) {
+ idx -= domain->hash_size - incr;
+ } else {
+ idx += incr;
+ }
+
+ nstr = SWAPIT(domain->must_swap, domain->hash_tab[idx]);
+ if( !nstr ) {
+ goto not_found; /* Hash table entry is empty. */
+ }
+
+ if ( SWAPIT(domain->must_swap,
+ domain->orig_tab[nstr - 1].length) == len
+ && !strcmp (msgid,
+ domain->data + SWAPIT(domain->must_swap,
+ domain->orig_tab[nstr - 1].offset))) {
+ return (char *)get_string( domain, nstr-1 );
+ }
+ }
+ /* NOTREACHED */
+ }
+
+ /* Now we try the default method: binary search in the sorted
+ array of messages. */
+ bottom = 0;
+ top = domain->nstrings;
+ while( bottom < top ) {
+ int cmp_val;
+
+ act = (bottom + top) / 2;
+ cmp_val = strcmp(msgid, domain->data
+ + SWAPIT(domain->must_swap,
+ domain->orig_tab[act].offset));
+ if (cmp_val < 0) {
+ top = act;
+ } else if (cmp_val > 0) {
+ bottom = act + 1;
+ } else {
+ return (char *)get_string( domain, (int)(act) );
+ }
}
- /* NOTREACHED */
- }
-
- /* Now we try the default method: binary search in the sorted
- array of messages. */
- bottom = 0;
- top = domain->nstrings;
- while( bottom < top ) {
- int cmp_val;
-
- act = (bottom + top) / 2;
- cmp_val = strcmp(msgid, domain->data
- + SWAPIT(domain->must_swap,
- domain->orig_tab[act].offset));
- if (cmp_val < 0)
- top = act;
- else if (cmp_val > 0)
- bottom = act + 1;
- else
- return (char *)get_string( domain, (int)(act) );
- }
-
- not_found:
- return (char *)msgid;
+
+not_found:
+ return (char *)msgid;
}
/**
- * This is the main initialization function for simple gettext. The message file is
- * opened and read into memory. The function must be called once before translating
+ * This is the main initialization function for simple gettext. The message file is
+ * opened and read into memory. The function must be called once before translating
* a string.
*
* The message files are expected to be in a directory named in the UNIXish form en_US
@@ -474,12 +477,13 @@ bindtextdomain( char *domainname, char *dirname )
loc = g_win32_getlocale();
/* make sure that path does not end with trailing slash */
- if( dirname[ strlen(dirname) ] == '/' )
+ if( dirname[ strlen(dirname) ] == '/' ) {
dirname[ strlen(dirname) ] = '\0';
+ }
/* allocate buffer for filename, 20 bytes should be enough for extension etc. */
dir = malloc( strlen( domainname ) + strlen( dirname ) + strlen( loc ) + 20 );
-
+
if( dir ) {
/* create the full filename */
sprintf( dir, "%s/%s/LC_MESSAGES/%s.mo", dirname, loc, domainname );
@@ -487,18 +491,18 @@ bindtextdomain( char *domainname, char *dirname )
set_gettext_file( dir, NULL );
free( dir );
}
-
+
free( loc );
return( NULL );
}
/**
- * This is a dummy function to maintain source code compatibility
+ * This is a dummy function to maintain source code compatibility
* with other implementations of gettext.
* For this implementation, UTF-8 input encoding is assumed
*
* \param domainname IN domain
- * \param codeset In codeset
+ * \param codeset In codeset
* \return always NULL
*/
@@ -509,7 +513,7 @@ bind_textdomain_codeset(char *domainname, char *codeset )
}
/**
- * This is a dummy function to maintain source code compatibility
+ * This is a dummy function to maintain source code compatibility
* with other implementations of gettext.
*
* \param domainname IN domain