* nlsfuncs.cc (rebase_locale_buf): New helper function to rebase

function pointers in locale structures.  Explain why this is necessary.
	(__set_lc_time_from_win): Use rebase_locale_buf after realloc.
	(__set_lc_numeric_from_win): Ditto.
	(__set_lc_monetary_from_win): Ditto.
This commit is contained in:
Corinna Vinschen 2010-04-01 20:13:22 +00:00
parent c1bfa897da
commit 57f7ebe1f2
2 changed files with 35 additions and 0 deletions

View File

@ -1,3 +1,11 @@
2010-04-01 Corinna Vinschen <corinna@vinschen.de>
* nlsfuncs.cc (rebase_locale_buf): New helper function to rebase
function pointers in locale structures. Explain why this is necessary.
(__set_lc_time_from_win): Use rebase_locale_buf after realloc.
(__set_lc_numeric_from_win): Ditto.
(__set_lc_monetary_from_win): Ditto.
2010-03-31 Christopher Faylor <me+cygwin@cgf.cx>
* sigproc.cc (wait_sig): Make sure that strace is activated on

View File

@ -325,6 +325,21 @@ locale_cmp (const void *a, const void *b)
return strcmp (*la, *lb);
}
/* Helper function to workaround reallocs which move blocks even if they shrink.
Cygwin's realloc is not doing this, but tcsh's, for instance. All lc_foo
structures consist entirely of pointers so they are practically pointer
arrays. What we do here is just treat the lc_foo pointers as char ** and
rebase all char * pointers within, up to the given size of the structure. */
static void
rebase_locale_buf (const void *ptrv, const char *newbase, const char *oldbase,
const void *ptrvend)
{
const char **ptrs = (const char **) ptrv;
const char **ptrsend = (const char **) ptrvend;
while (ptrs < ptrsend)
*ptrs++ += newbase - oldbase;
}
static char *
__getlocaleinfo (LCID lcid, LCTYPE type, char **ptr, size_t size,
wctomb_p f_wctomb, const char *charset)
@ -625,6 +640,9 @@ __set_lc_time_from_win (const char *name, struct lc_time_T *_time_locale,
era = NULL;
else
{
if (tmp != new_lc_time_buf)
rebase_locale_buf (_time_locale, tmp, new_lc_time_buf,
_time_locale + 1);
lc_time_ptr = tmp + (lc_time_ptr - new_lc_time_buf);
new_lc_time_buf = tmp;
lc_time_end = new_lc_time_buf + len;
@ -674,6 +692,9 @@ __set_lc_time_from_win (const char *name, struct lc_time_T *_time_locale,
free (new_lc_time_buf);
return -1;
}
if (tmp != new_lc_time_buf)
rebase_locale_buf (_time_locale, tmp, new_lc_time_buf,
_time_locale + 1);
if (*lc_time_buf)
free (*lc_time_buf);
*lc_time_buf = tmp;
@ -717,6 +738,9 @@ __set_lc_numeric_from_win (const char *name,
free (new_lc_numeric_buf);
return -1;
}
if (tmp != new_lc_numeric_buf)
rebase_locale_buf (_numeric_locale, tmp, new_lc_numeric_buf,
_numeric_locale + 1);
if (*lc_numeric_buf)
free (*lc_numeric_buf);
*lc_numeric_buf = tmp;
@ -816,6 +840,9 @@ __set_lc_monetary_from_win (const char *name,
free (new_lc_monetary_buf);
return -1;
}
if (tmp != new_lc_monetary_buf)
rebase_locale_buf (_monetary_locale, tmp, new_lc_monetary_buf,
_monetary_locale + 1);
if (*lc_monetary_buf)
free (*lc_monetary_buf);
*lc_monetary_buf = tmp;