diff options
| author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2024-11-14 19:35:45 +0100 | 
|---|---|---|
| committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2024-11-14 19:35:45 +0100 | 
| commit | df5520aa2dae5b3ce7abf8733dcdd152898af163 (patch) | |
| tree | 00d3047bfb14f682bfb5a21010c731ed649bfed7 /app/wlib/mswlib/simple-gettext.c | |
| parent | df247efec654e512242e4f4f1b0212034f9e01fe (diff) | |
| parent | ec3c0f6f6e7153fa797dc57a0e95779cbc63a23b (diff) | |
Merge branch 'release/debian/1_5.3.0GA-1'debian/1_5.3.0GA-1
Diffstat (limited to 'app/wlib/mswlib/simple-gettext.c')
| -rw-r--r-- | app/wlib/mswlib/simple-gettext.c | 600 | 
1 files changed, 302 insertions, 298 deletions
| diff --git a/app/wlib/mswlib/simple-gettext.c b/app/wlib/mswlib/simple-gettext.c index 412eece..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 = 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, 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 = 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, 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 | 
