Skip to content

Commit

Permalink
locale.c: Use parallel array to simplify
Browse files Browse the repository at this point in the history
This allows the numeric fields returned by localeconv() to have the same
logic as the string fields, simplifying the code a bit.  They weren't
previously handled the same because one category doesn't have any
numeric fields.  But this is now handled by creating an array and making
its corresponding element NULL, so the strings and numeric fields are
handled in the same way.
  • Loading branch information
khwilliamson committed Nov 20, 2023
1 parent e6c9cc7 commit 6ac1a8e
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 30 deletions.
12 changes: 6 additions & 6 deletions embed.fnc
Expand Up @@ -4408,12 +4408,12 @@ Sf |char * |strftime_tm |NN const char *fmt \
|NN const struct tm *mytm
# if defined(HAS_LOCALECONV)
S |HV * |my_localeconv |const int item
S |void |populate_hash_from_localeconv \
|NN HV *hv \
|NN const char *locale \
|const PERL_UINT_FAST8_T which_mask \
|NN const lconv_offset_t *strings[2] \
|NULLOK const lconv_offset_t *integers
S |void |populate_hash_from_localeconv \
|NN HV *hv \
|NN const char *locale \
|const PERL_UINT_FAST8_T which_mask \
|NN const lconv_offset_t *strings[2] \
|NULLOK const lconv_offset_t *integers[2]
# endif
# if defined(USE_LOCALE)
S |const char *|calculate_LC_ALL_string \
Expand Down
51 changes: 28 additions & 23 deletions locale.c
Expand Up @@ -5452,6 +5452,13 @@ S_my_localeconv(pTHX_ const int item)
lconv_monetary_strings
};

/* The LC_MONETARY category also has some integer-valued fields, whose
* information is kept in a separate parallel array to 'strings' */
const lconv_offset_t * integers[2] = {
NULL,
lconv_integers
};

/* This is a mask, with one bit to tell the populate functions to populate
* the NUMERIC items; another bit for the MONETARY ones. This way they can
* choose which (or both) to populate from */
Expand Down Expand Up @@ -5497,10 +5504,6 @@ S_my_localeconv(pTHX_ const int item)
* what we are working on at the moment */
const char * locale;

/* The LC_MONETARY category also has some integer-valued fields, whose
* information is kept in a separate list */
const lconv_offset_t * integers = lconv_integers;

# ifdef HAS_SOME_LANGINFO

/* If the only use-case for this is the full localeconv(), the 'item'
Expand Down Expand Up @@ -5565,7 +5568,6 @@ S_my_localeconv(pTHX_ const int item)
strings[NUMERIC_OFFSET] = thousands_sep_string;

numeric_common:
integers = NULL;
index_bits = OFFSET_TO_BIT(NUMERIC_OFFSET);
locale = numeric_locale = PL_numeric_name;
break;
Expand All @@ -5584,7 +5586,7 @@ S_my_localeconv(pTHX_ const int item)
}

strings[MONETARY_OFFSET] = CURRENCY_SYMBOL_ADDRESS;
integers = P_CS_PRECEDES_ADDRESS;
integers[MONETARY_OFFSET] = P_CS_PRECEDES_ADDRESS;

index_bits = OFFSET_TO_BIT(MONETARY_OFFSET);
locale = monetary_locale = querylocale_i(LC_MONETARY_INDEX_);
Expand Down Expand Up @@ -5651,10 +5653,7 @@ S_my_localeconv(pTHX_ const int item)
populate_hash_from_localeconv(hv,
numeric_locale,
OFFSET_TO_BIT(NUMERIC_OFFSET),
strings,
NULL /* There are no NUMERIC integer
fields */
);
strings, integers);
}

/* Here, the hash has been completely populated.
Expand Down Expand Up @@ -5724,12 +5723,14 @@ S_my_localeconv(pTHX_ const int item)
SvUTF8_on(*value);
}
}
} /* End of fixing up UTF8ness */

if (integers[i] == NULL) {
continue;
}

/* Examine each integer */
for (; integers; integers++) {
const char * name = integers->name;
/* And each integer */
for (const lconv_offset_t *intp = integers[i]; intp->name; intp++) {
const char * name = intp->name;

if (! name) { /* Reached the end */
break;
Expand All @@ -5744,6 +5745,7 @@ S_my_localeconv(pTHX_ const int item)
if (SvIV(*value) == CHAR_MAX) {
sv_setiv(*value, -1);
}
}
}

return hv;
Expand All @@ -5765,8 +5767,8 @@ S_populate_hash_from_localeconv(pTHX_ HV * hv,
* monetary */
const lconv_offset_t * strings[2],

/* And to the monetary integer fields */
const lconv_offset_t * integers)
/* And similarly the integer fields */
const lconv_offset_t * integers[2])
{
PERL_ARGS_ASSERT_POPULATE_HASH_FROM_LOCALECONV;
PERL_UNUSED_ARG(which_mask); /* Some configurations don't use this;
Expand Down Expand Up @@ -5915,14 +5917,17 @@ S_populate_hash_from_localeconv(pTHX_ HV * hv,
category_strings++;
}

/* Add any int fields to the HV* */
if (i == MONETARY_OFFSET && integers) {
while (integers->name) {
/* Add any int fields to the HV*. */
if (integers[i]) {
const lconv_offset_t * current = integers[i];
while (current->name) {
const char value = *((const char *)( lcbuf_as_string
+ integers->offset));
(void) hv_store(hv, integers->name,
strlen(integers->name), newSViv(value), 0);
integers++;
+ current->offset));
(void) hv_store(hv,
current->name, strlen(current->name),
newSViv(value),
0);
current++;
}
}
} /* End of loop through the fields */
Expand Down
2 changes: 1 addition & 1 deletion proto.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6ac1a8e

Please sign in to comment.