msvcp: Sync num_get<>::_Getifld.
This commit is contained in:
parent
c99a19208a
commit
4c357de5d3
|
@ -3976,10 +3976,11 @@ static int num_get__Getifld(const num_get *this, char *dest, istreambuf_iterator
|
|||
{
|
||||
wchar_t digits[23], *digits_pos, sep;
|
||||
basic_string_char grouping_bstr;
|
||||
basic_string_char groups_found;
|
||||
int i, basefield, base, groups_no = 0, cur_group = 0;
|
||||
char *dest_beg = dest, *dest_end = dest+24, *groups = NULL;
|
||||
const char *grouping;
|
||||
BOOL error = TRUE, dest_empty = TRUE;
|
||||
char *dest_beg = dest, *dest_end = dest+24;
|
||||
const char *grouping, *groups;
|
||||
BOOL error = TRUE, dest_empty = TRUE, found_zero = FALSE;
|
||||
|
||||
TRACE("(%p %p %p %04x %p)\n", dest, first, last, fmtflags, loc);
|
||||
|
||||
|
@ -4013,46 +4014,48 @@ static int num_get__Getifld(const num_get *this, char *dest, istreambuf_iterator
|
|||
istreambuf_iterator_wchar_inc(first);
|
||||
}
|
||||
|
||||
if(!base && first->strbuf && first->val==digits[0]) {
|
||||
if(first->strbuf && first->val==digits[0]) {
|
||||
found_zero = TRUE;
|
||||
istreambuf_iterator_wchar_inc(first);
|
||||
if(first->strbuf && (first->val==mb_to_wc('x', &this->cvt) || first->val==mb_to_wc('x', &this->cvt))) {
|
||||
istreambuf_iterator_wchar_inc(first);
|
||||
base = 22;
|
||||
if(first->strbuf && (first->val==mb_to_wc('x', &this->cvt) || first->val==mb_to_wc('X', &this->cvt))) {
|
||||
if(!base || base == 22) {
|
||||
found_zero = FALSE;
|
||||
istreambuf_iterator_wchar_inc(first);
|
||||
base = 22;
|
||||
}else {
|
||||
base = 10;
|
||||
}
|
||||
}else {
|
||||
error = FALSE;
|
||||
base = 8;
|
||||
if(!base) base = 8;
|
||||
}
|
||||
}else {
|
||||
base = 10;
|
||||
if(!base) base = 10;
|
||||
}
|
||||
digits[base] = 0;
|
||||
|
||||
if(sep) {
|
||||
groups_no = strlen(grouping)+2;
|
||||
groups = calloc(groups_no, sizeof(char));
|
||||
MSVCP_basic_string_char_ctor(&groups_found);
|
||||
if(found_zero) ++groups_no;
|
||||
}
|
||||
|
||||
for(; first->strbuf; istreambuf_iterator_wchar_inc(first)) {
|
||||
if(!(digits_pos = wcschr(digits, first->val))) {
|
||||
if(sep && first->val==sep) {
|
||||
if(cur_group == groups_no+1) {
|
||||
if(groups[1] != groups[2]) {
|
||||
error = TRUE;
|
||||
break;
|
||||
}else {
|
||||
memmove(groups+1, groups+2, groups_no);
|
||||
groups[cur_group] = 0;
|
||||
}
|
||||
}else {
|
||||
cur_group++;
|
||||
}
|
||||
if(!groups_no) break; /* empty group - stop parsing */
|
||||
MSVCP_basic_string_char_append_ch(&groups_found, groups_no);
|
||||
groups_no = 0;
|
||||
++cur_group;
|
||||
}else {
|
||||
break;
|
||||
}
|
||||
}else {
|
||||
error = FALSE;
|
||||
if(dest_empty && first->val == digits[0])
|
||||
if(dest_empty && first->val == digits[0]) {
|
||||
found_zero = TRUE;
|
||||
++groups_no;
|
||||
continue;
|
||||
}
|
||||
dest_empty = FALSE;
|
||||
/* skip digits that can't be copied to dest buffer, other
|
||||
* functions are responsible for detecting overflows */
|
||||
|
@ -4060,14 +4063,20 @@ static int num_get__Getifld(const num_get *this, char *dest, istreambuf_iterator
|
|||
*dest++ = (digits_pos-digits<10 ? '0'+digits_pos-digits :
|
||||
(digits_pos-digits<16 ? 'a'+digits_pos-digits-10 :
|
||||
'A'+digits_pos-digits-16));
|
||||
if(sep && groups[cur_group]<CHAR_MAX)
|
||||
groups[cur_group]++;
|
||||
if(sep && groups_no<CHAR_MAX)
|
||||
++groups_no;
|
||||
}
|
||||
}
|
||||
|
||||
if(sep && groups_no)
|
||||
MSVCP_basic_string_char_append_ch(&groups_found, groups_no);
|
||||
|
||||
groups = MSVCP_basic_string_char_c_str(&groups_found);
|
||||
if(cur_group && !groups[cur_group])
|
||||
error = TRUE;
|
||||
else if(!cur_group)
|
||||
{
|
||||
error = TRUE; /* trailing empty */
|
||||
found_zero = FALSE;
|
||||
}else if(!cur_group) /* no groups, skip loop */
|
||||
cur_group--;
|
||||
|
||||
for(; cur_group>=0 && !error; cur_group--) {
|
||||
|
@ -4083,12 +4092,17 @@ static int num_get__Getifld(const num_get *this, char *dest, istreambuf_iterator
|
|||
grouping++;
|
||||
}
|
||||
}
|
||||
MSVCP_basic_string_char_dtor(&grouping_bstr);
|
||||
free(groups);
|
||||
|
||||
if(error)
|
||||
dest = dest_beg;
|
||||
else if(dest_empty)
|
||||
MSVCP_basic_string_char_dtor(&grouping_bstr);
|
||||
if(sep)
|
||||
MSVCP_basic_string_char_dtor(&groups_found);
|
||||
|
||||
if(error) {
|
||||
if (found_zero)
|
||||
*dest++ = '0';
|
||||
else
|
||||
dest = dest_beg;
|
||||
}else if(dest_empty)
|
||||
*dest++ = '0';
|
||||
*dest = '\0';
|
||||
|
||||
|
@ -5067,10 +5081,11 @@ int __cdecl num_get_char__Getifld(const num_get *this, char *dest, istreambuf_it
|
|||
|
||||
numpunct_char *numpunct = numpunct_char_use_facet(loc);
|
||||
basic_string_char grouping_bstr;
|
||||
basic_string_char groups_found;
|
||||
int basefield, base, groups_no = 0, cur_group = 0;
|
||||
char *dest_beg = dest, *dest_end = dest+24, *groups = NULL, sep;
|
||||
const char *grouping;
|
||||
BOOL error = TRUE, dest_empty = TRUE;
|
||||
char *dest_beg = dest, *dest_end = dest+24, sep;
|
||||
const char *grouping, *groups;
|
||||
BOOL error = TRUE, dest_empty = TRUE, found_zero = FALSE;
|
||||
|
||||
TRACE("(%p %p %p %04x %p)\n", dest, first, last, fmtflags, loc);
|
||||
|
||||
|
@ -5094,58 +5109,68 @@ int __cdecl num_get_char__Getifld(const num_get *this, char *dest, istreambuf_it
|
|||
istreambuf_iterator_char_inc(first);
|
||||
}
|
||||
|
||||
if(!base && first->strbuf && first->val=='0') {
|
||||
if(first->strbuf && first->val=='0') {
|
||||
found_zero = TRUE;
|
||||
istreambuf_iterator_char_inc(first);
|
||||
if(first->strbuf && (first->val=='x' || first->val=='X')) {
|
||||
istreambuf_iterator_char_inc(first);
|
||||
base = 22;
|
||||
if(!base || base == 22) {
|
||||
found_zero = FALSE;
|
||||
istreambuf_iterator_char_inc(first);
|
||||
base = 22;
|
||||
}else {
|
||||
base = 10;
|
||||
}
|
||||
}else {
|
||||
error = FALSE;
|
||||
base = 8;
|
||||
if(!base) base = 8;
|
||||
}
|
||||
}else {
|
||||
base = 10;
|
||||
if (!base) base = 10;
|
||||
}
|
||||
|
||||
if(sep) {
|
||||
groups_no = strlen(grouping)+2;
|
||||
groups = calloc(groups_no, sizeof(char));
|
||||
if(sep)
|
||||
{
|
||||
MSVCP_basic_string_char_ctor(&groups_found);
|
||||
if(found_zero) ++groups_no;
|
||||
}
|
||||
|
||||
for(; first->strbuf; istreambuf_iterator_char_inc(first)) {
|
||||
if(!memchr(digits, first->val, base)) {
|
||||
if(sep && first->val==sep) {
|
||||
if(cur_group == groups_no+1) {
|
||||
if(groups[1] != groups[2]) {
|
||||
error = TRUE;
|
||||
break;
|
||||
}else {
|
||||
memmove(groups+1, groups+2, groups_no);
|
||||
groups[cur_group] = 0;
|
||||
}
|
||||
}else {
|
||||
cur_group++;
|
||||
}
|
||||
if(!groups_no) break; /* empty group - stop parsing */
|
||||
MSVCP_basic_string_char_append_ch(&groups_found, groups_no);
|
||||
groups_no = 0;
|
||||
++cur_group;
|
||||
}else {
|
||||
break;
|
||||
}
|
||||
}else {
|
||||
error = FALSE;
|
||||
if(dest_empty && first->val == '0')
|
||||
{
|
||||
found_zero = TRUE;
|
||||
++groups_no;
|
||||
continue;
|
||||
}
|
||||
dest_empty = FALSE;
|
||||
/* skip digits that can't be copied to dest buffer, other
|
||||
* functions are responsible for detecting overflows */
|
||||
if(dest < dest_end)
|
||||
*dest++ = first->val;
|
||||
if(sep && groups[cur_group]<CHAR_MAX)
|
||||
groups[cur_group]++;
|
||||
if(sep && groups_no<CHAR_MAX)
|
||||
++groups_no;
|
||||
}
|
||||
}
|
||||
|
||||
if(sep && groups_no)
|
||||
MSVCP_basic_string_char_append_ch(&groups_found, groups_no);
|
||||
|
||||
groups = MSVCP_basic_string_char_c_str(&groups_found);
|
||||
if(cur_group && !groups[cur_group])
|
||||
error = TRUE;
|
||||
else if(!cur_group)
|
||||
{
|
||||
error = TRUE; /* trailing empty */
|
||||
found_zero = FALSE;
|
||||
}else if(!cur_group) /* no groups, skip loop */
|
||||
cur_group--;
|
||||
|
||||
for(; cur_group>=0 && !error; cur_group--) {
|
||||
|
@ -5161,12 +5186,17 @@ int __cdecl num_get_char__Getifld(const num_get *this, char *dest, istreambuf_it
|
|||
grouping++;
|
||||
}
|
||||
}
|
||||
MSVCP_basic_string_char_dtor(&grouping_bstr);
|
||||
free(groups);
|
||||
|
||||
if(error)
|
||||
dest = dest_beg;
|
||||
else if(dest_empty)
|
||||
MSVCP_basic_string_char_dtor(&grouping_bstr);
|
||||
if(sep)
|
||||
MSVCP_basic_string_char_dtor(&groups_found);
|
||||
|
||||
if(error) {
|
||||
if (found_zero)
|
||||
*dest++ = '0';
|
||||
else
|
||||
dest = dest_beg;
|
||||
}else if(dest_empty)
|
||||
*dest++ = '0';
|
||||
*dest = '\0';
|
||||
|
||||
|
|
|
@ -48,10 +48,12 @@ typedef struct
|
|||
MSVCP_size_t res;
|
||||
} basic_string_char;
|
||||
|
||||
basic_string_char* MSVCP_basic_string_char_ctor(basic_string_char*);
|
||||
basic_string_char* MSVCP_basic_string_char_ctor_cstr(basic_string_char*, const char*);
|
||||
basic_string_char* MSVCP_basic_string_char_copy_ctor(basic_string_char*, const basic_string_char*);
|
||||
void MSVCP_basic_string_char_dtor(basic_string_char*);
|
||||
const char* MSVCP_basic_string_char_c_str(const basic_string_char*);
|
||||
basic_string_char* MSVCP_basic_string_char_append_ch(basic_string_char*, char);
|
||||
MSVCP_size_t MSVCP_basic_string_char_length(const basic_string_char*);
|
||||
|
||||
#define BUF_SIZE_WCHAR 8
|
||||
|
|
|
@ -38,6 +38,13 @@ static void MSVCP_char_traits_char_assign(char *ch, const char *assign)
|
|||
*ch = *assign;
|
||||
}
|
||||
|
||||
/* ?assign@?$char_traits@D@std@@SAPADPADID@Z */
|
||||
/* ?assign@?$char_traits@D@std@@SAPEADPEAD_KD@Z */
|
||||
static char* MSVCP_char_traits_char_assignn(char *str, MSVCP_size_t num, char c)
|
||||
{
|
||||
return memset(str, c, num);
|
||||
}
|
||||
|
||||
/* ?length@?$char_traits@D@std@@SAIPBD@Z */
|
||||
/* ?length@?$char_traits@D@std@@SA_KPEBD@Z */
|
||||
static MSVCP_size_t MSVCP_char_traits_char_length(const char *str)
|
||||
|
@ -121,6 +128,16 @@ static wchar_t* MSVCP_char_traits_wchar__Move_s(wchar_t *dest,
|
|||
return memmove(dest, src, count * sizeof(WCHAR));
|
||||
}
|
||||
|
||||
/* _String_base */
|
||||
/* ?_Xlen@_String_base@std@@SAXXZ */
|
||||
static void MSVCP__String_base_Xlen(void)
|
||||
{
|
||||
static const char msg[] = "string too long";
|
||||
|
||||
TRACE("\n");
|
||||
throw_exception(EXCEPTION_LENGTH_ERROR, msg);
|
||||
}
|
||||
|
||||
/* _String_base */
|
||||
/* ?_Xran@_String_base@std@@SAXXZ */
|
||||
static void MSVCP__String_base_Xran(void)
|
||||
|
@ -340,6 +357,16 @@ basic_string_char* MSVCP_basic_string_char_copy_ctor(
|
|||
return this;
|
||||
}
|
||||
|
||||
/* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ */
|
||||
/* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@XZ */
|
||||
basic_string_char* MSVCP_basic_string_char_ctor(basic_string_char *this)
|
||||
{
|
||||
TRACE("%p\n", this);
|
||||
|
||||
basic_string_char_tidy(this, FALSE, 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
/* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z */
|
||||
/* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@PEBD@Z */
|
||||
basic_string_char* MSVCP_basic_string_char_ctor_cstr(
|
||||
|
@ -370,6 +397,32 @@ MSVCP_size_t MSVCP_basic_string_char_length(const basic_string_char *this)
|
|||
return this->size;
|
||||
}
|
||||
|
||||
/* ?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@ID@Z */
|
||||
/* ?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@_KD@Z */
|
||||
basic_string_char* MSVCP_basic_string_char_append_len_ch(basic_string_char *this, MSVCP_size_t count, char ch)
|
||||
{
|
||||
TRACE("%p %lu %c\n", this, count, ch);
|
||||
|
||||
if(MSVCP_basic_string_char_npos-this->size <= count)
|
||||
MSVCP__String_base_Xlen();
|
||||
|
||||
if(basic_string_char_grow(this, this->size+count, FALSE)) {
|
||||
MSVCP_char_traits_char_assignn(basic_string_char_ptr(this)+this->size, count, ch);
|
||||
basic_string_char_eos(this, this->size+count);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/* ??Y?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@D@Z */
|
||||
/* ??Y?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV01@D@Z */
|
||||
/* ?push_back@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEXD@Z */
|
||||
/* ?push_back@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAXD@Z */
|
||||
basic_string_char* MSVCP_basic_string_char_append_ch(basic_string_char *this, char ch)
|
||||
{
|
||||
return MSVCP_basic_string_char_append_len_ch(this, 1, ch);
|
||||
}
|
||||
|
||||
/* basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> */
|
||||
/* basic_string<unsigned short, char_traits<unsigned short>, allocator<unsigned short>> */
|
||||
/* ?npos@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@2IB */
|
||||
|
|
|
@ -4116,10 +4116,11 @@ static int num_get__Getifld(const num_get *this, char *dest, istreambuf_iterator
|
|||
{
|
||||
wchar_t digits[23], *digits_pos, sep;
|
||||
basic_string_char grouping_bstr;
|
||||
basic_string_char groups_found;
|
||||
int i, basefield, base, groups_no = 0, cur_group = 0;
|
||||
char *dest_beg = dest, *dest_end = dest+24, *groups = NULL;
|
||||
const char *grouping;
|
||||
BOOL error = TRUE, dest_empty = TRUE;
|
||||
char *dest_beg = dest, *dest_end = dest+24;
|
||||
const char *grouping, *groups;
|
||||
BOOL error = TRUE, dest_empty = TRUE, found_zero = FALSE;
|
||||
|
||||
TRACE("(%p %p %p %04x %p)\n", dest, first, last, fmtflags, loc);
|
||||
|
||||
|
@ -4132,7 +4133,7 @@ static int num_get__Getifld(const num_get *this, char *dest, istreambuf_iterator
|
|||
|
||||
numpunct_wchar_grouping(numpunct, &grouping_bstr);
|
||||
grouping = basic_string_char_c_str(&grouping_bstr);
|
||||
sep = grouping[0] ? numpunct_wchar_thousands_sep(numpunct) : '\0';
|
||||
sep = grouping ? numpunct_wchar_thousands_sep(numpunct) : '\0';
|
||||
|
||||
basefield = fmtflags & FMTFLAG_basefield;
|
||||
if(basefield == FMTFLAG_oct)
|
||||
|
@ -4153,46 +4154,48 @@ static int num_get__Getifld(const num_get *this, char *dest, istreambuf_iterator
|
|||
istreambuf_iterator_wchar_inc(first);
|
||||
}
|
||||
|
||||
if(!base && first->strbuf && first->val==digits[0]) {
|
||||
if(first->strbuf && first->val==digits[0]) {
|
||||
found_zero = TRUE;
|
||||
istreambuf_iterator_wchar_inc(first);
|
||||
if(first->strbuf && (first->val==mb_to_wc('x', &this->cvt) || first->val==mb_to_wc('x', &this->cvt))) {
|
||||
istreambuf_iterator_wchar_inc(first);
|
||||
base = 22;
|
||||
if(first->strbuf && (first->val==mb_to_wc('x', &this->cvt) || first->val==mb_to_wc('X', &this->cvt))) {
|
||||
if(!base || base == 22) {
|
||||
found_zero = FALSE;
|
||||
istreambuf_iterator_wchar_inc(first);
|
||||
base = 22;
|
||||
}else {
|
||||
base = 10;
|
||||
}
|
||||
}else {
|
||||
error = FALSE;
|
||||
base = 8;
|
||||
if(!base) base = 8;
|
||||
}
|
||||
}else {
|
||||
base = 10;
|
||||
if(!base) base = 10;
|
||||
}
|
||||
digits[base] = 0;
|
||||
|
||||
if(sep) {
|
||||
groups_no = strlen(grouping)+2;
|
||||
groups = calloc(groups_no, sizeof(char));
|
||||
basic_string_char_ctor(&groups_found);
|
||||
if(found_zero) ++groups_no;
|
||||
}
|
||||
|
||||
for(; first->strbuf; istreambuf_iterator_wchar_inc(first)) {
|
||||
if(!(digits_pos = wcschr(digits, first->val))) {
|
||||
if(sep && first->val==sep) {
|
||||
if(cur_group == groups_no+1) {
|
||||
if(groups[1] != groups[2]) {
|
||||
error = TRUE;
|
||||
break;
|
||||
}else {
|
||||
memmove(groups+1, groups+2, groups_no);
|
||||
groups[cur_group] = 0;
|
||||
}
|
||||
}else {
|
||||
cur_group++;
|
||||
}
|
||||
if(!groups_no) break; /* empty group - stop parsing */
|
||||
basic_string_char_append_ch(&groups_found, groups_no);
|
||||
groups_no = 0;
|
||||
++cur_group;
|
||||
}else {
|
||||
break;
|
||||
}
|
||||
}else {
|
||||
error = FALSE;
|
||||
if(dest_empty && first->val == digits[0])
|
||||
if(dest_empty && first->val == digits[0]) {
|
||||
found_zero = TRUE;
|
||||
++groups_no;
|
||||
continue;
|
||||
}
|
||||
dest_empty = FALSE;
|
||||
/* skip digits that can't be copied to dest buffer, other
|
||||
* functions are responsible for detecting overflows */
|
||||
|
@ -4200,14 +4203,20 @@ static int num_get__Getifld(const num_get *this, char *dest, istreambuf_iterator
|
|||
*dest++ = (digits_pos-digits<10 ? '0'+digits_pos-digits :
|
||||
(digits_pos-digits<16 ? 'a'+digits_pos-digits-10 :
|
||||
'A'+digits_pos-digits-16));
|
||||
if(sep && groups[cur_group]<CHAR_MAX)
|
||||
groups[cur_group]++;
|
||||
if(sep && groups_no<CHAR_MAX)
|
||||
++groups_no;
|
||||
}
|
||||
}
|
||||
|
||||
if(cur_group && !groups[cur_group])
|
||||
error = TRUE;
|
||||
else if(!cur_group)
|
||||
if(sep && groups_no)
|
||||
basic_string_char_append_ch(&groups_found, groups_no);
|
||||
|
||||
groups = basic_string_char_c_str(&groups_found);
|
||||
if(cur_group && groups && !groups[cur_group])
|
||||
{
|
||||
error = TRUE; /* trailing empty */
|
||||
found_zero = FALSE;
|
||||
}else if(!cur_group) /* no groups, skip loop */
|
||||
cur_group--;
|
||||
|
||||
for(; cur_group>=0 && !error; cur_group--) {
|
||||
|
@ -4223,12 +4232,17 @@ static int num_get__Getifld(const num_get *this, char *dest, istreambuf_iterator
|
|||
grouping++;
|
||||
}
|
||||
}
|
||||
basic_string_char_dtor(&grouping_bstr);
|
||||
free(groups);
|
||||
|
||||
if(error)
|
||||
dest = dest_beg;
|
||||
else if(dest_empty)
|
||||
basic_string_char_dtor(&grouping_bstr);
|
||||
if(sep)
|
||||
basic_string_char_dtor(&groups_found);
|
||||
|
||||
if(error) {
|
||||
if (found_zero)
|
||||
*dest++ = '0';
|
||||
else
|
||||
dest = dest_beg;
|
||||
}else if(dest_empty)
|
||||
*dest++ = '0';
|
||||
*dest = '\0';
|
||||
|
||||
|
@ -5177,10 +5191,11 @@ static int num_get_char__Getifld(const num_get *this, char *dest, istreambuf_ite
|
|||
|
||||
numpunct_char *numpunct = numpunct_char_use_facet(loc);
|
||||
basic_string_char grouping_bstr;
|
||||
basic_string_char groups_found;
|
||||
int basefield, base, groups_no = 0, cur_group = 0;
|
||||
char *dest_beg = dest, *dest_end = dest+24, *groups = NULL, sep;
|
||||
const char *grouping;
|
||||
BOOL error = TRUE, dest_empty = TRUE;
|
||||
char *dest_beg = dest, *dest_end = dest+24, sep;
|
||||
const char *grouping, *groups;
|
||||
BOOL error = TRUE, dest_empty = TRUE, found_zero = FALSE;
|
||||
|
||||
TRACE("(%p %p %p %04x %p)\n", dest, first, last, fmtflags, loc);
|
||||
|
||||
|
@ -5204,58 +5219,68 @@ static int num_get_char__Getifld(const num_get *this, char *dest, istreambuf_ite
|
|||
istreambuf_iterator_char_inc(first);
|
||||
}
|
||||
|
||||
if(!base && first->strbuf && first->val=='0') {
|
||||
if(first->strbuf && first->val=='0') {
|
||||
found_zero = TRUE;
|
||||
istreambuf_iterator_char_inc(first);
|
||||
if(first->strbuf && (first->val=='x' || first->val=='X')) {
|
||||
istreambuf_iterator_char_inc(first);
|
||||
base = 22;
|
||||
if(!base || base == 22) {
|
||||
found_zero = FALSE;
|
||||
istreambuf_iterator_char_inc(first);
|
||||
base = 22;
|
||||
}else {
|
||||
base = 10;
|
||||
}
|
||||
}else {
|
||||
error = FALSE;
|
||||
base = 8;
|
||||
if(!base) base = 8;
|
||||
}
|
||||
}else {
|
||||
base = 10;
|
||||
if (!base) base = 10;
|
||||
}
|
||||
|
||||
if(sep) {
|
||||
groups_no = strlen(grouping)+2;
|
||||
groups = calloc(groups_no, sizeof(char));
|
||||
if(sep)
|
||||
{
|
||||
basic_string_char_ctor(&groups_found);
|
||||
if(found_zero) ++groups_no;
|
||||
}
|
||||
|
||||
for(; first->strbuf; istreambuf_iterator_char_inc(first)) {
|
||||
if(!memchr(digits, first->val, base)) {
|
||||
if(sep && first->val==sep) {
|
||||
if(cur_group == groups_no+1) {
|
||||
if(groups[1] != groups[2]) {
|
||||
error = TRUE;
|
||||
break;
|
||||
}else {
|
||||
memmove(groups+1, groups+2, groups_no);
|
||||
groups[cur_group] = 0;
|
||||
}
|
||||
}else {
|
||||
cur_group++;
|
||||
}
|
||||
if(!groups_no) break; /* empty group - stop parsing */
|
||||
basic_string_char_append_ch(&groups_found, groups_no);
|
||||
groups_no = 0;
|
||||
++cur_group;
|
||||
}else {
|
||||
break;
|
||||
}
|
||||
}else {
|
||||
error = FALSE;
|
||||
if(dest_empty && first->val == '0')
|
||||
{
|
||||
found_zero = TRUE;
|
||||
++groups_no;
|
||||
continue;
|
||||
}
|
||||
dest_empty = FALSE;
|
||||
/* skip digits that can't be copied to dest buffer, other
|
||||
* functions are responsible for detecting overflows */
|
||||
if(dest < dest_end)
|
||||
*dest++ = first->val;
|
||||
if(sep && groups[cur_group]<CHAR_MAX)
|
||||
groups[cur_group]++;
|
||||
if(sep && groups_no<CHAR_MAX)
|
||||
++groups_no;
|
||||
}
|
||||
}
|
||||
|
||||
if(cur_group && !groups[cur_group])
|
||||
error = TRUE;
|
||||
else if(!cur_group)
|
||||
if(sep && groups_no)
|
||||
basic_string_char_append_ch(&groups_found, groups_no);
|
||||
|
||||
groups = basic_string_char_c_str(&groups_found);
|
||||
if(cur_group && groups && !groups[cur_group])
|
||||
{
|
||||
error = TRUE; /* trailing empty */
|
||||
found_zero = FALSE;
|
||||
}else if(!cur_group) /* no groups, skip loop */
|
||||
cur_group--;
|
||||
|
||||
for(; cur_group>=0 && !error; cur_group--) {
|
||||
|
@ -5271,12 +5296,17 @@ static int num_get_char__Getifld(const num_get *this, char *dest, istreambuf_ite
|
|||
grouping++;
|
||||
}
|
||||
}
|
||||
basic_string_char_dtor(&grouping_bstr);
|
||||
free(groups);
|
||||
|
||||
if(error)
|
||||
dest = dest_beg;
|
||||
else if(dest_empty)
|
||||
basic_string_char_dtor(&grouping_bstr);
|
||||
if(sep)
|
||||
basic_string_char_dtor(&groups_found);
|
||||
|
||||
if(error) {
|
||||
if (found_zero)
|
||||
*dest++ = '0';
|
||||
else
|
||||
dest = dest_beg;
|
||||
}else if(dest_empty)
|
||||
*dest++ = '0';
|
||||
*dest = '\0';
|
||||
|
||||
|
|
|
@ -4399,10 +4399,11 @@ static int num_get__Getifld(const num_get *this, char *dest, istreambuf_iterator
|
|||
{
|
||||
wchar_t digits[23], *digits_pos, sep;
|
||||
basic_string_char grouping_bstr;
|
||||
basic_string_char groups_found;
|
||||
int i, basefield, base, groups_no = 0, cur_group = 0;
|
||||
char *dest_beg = dest, *dest_end = dest+24, *groups = NULL;
|
||||
const char *grouping;
|
||||
BOOL error = TRUE, dest_empty = TRUE;
|
||||
char *dest_beg = dest, *dest_end = dest+24;
|
||||
const char *grouping, *groups;
|
||||
BOOL error = TRUE, dest_empty = TRUE, found_zero = FALSE;
|
||||
|
||||
TRACE("(%p %p %p %04x %p)\n", dest, first, last, fmtflags, loc);
|
||||
|
||||
|
@ -4436,46 +4437,48 @@ static int num_get__Getifld(const num_get *this, char *dest, istreambuf_iterator
|
|||
istreambuf_iterator_wchar_inc(first);
|
||||
}
|
||||
|
||||
if(!base && first->strbuf && first->val==digits[0]) {
|
||||
if(first->strbuf && first->val==digits[0]) {
|
||||
found_zero = TRUE;
|
||||
istreambuf_iterator_wchar_inc(first);
|
||||
if(first->strbuf && (first->val==mb_to_wc('x', &this->cvt) || first->val==mb_to_wc('x', &this->cvt))) {
|
||||
istreambuf_iterator_wchar_inc(first);
|
||||
base = 22;
|
||||
if(first->strbuf && (first->val==mb_to_wc('x', &this->cvt) || first->val==mb_to_wc('X', &this->cvt))) {
|
||||
if(!base || base == 22) {
|
||||
found_zero = FALSE;
|
||||
istreambuf_iterator_wchar_inc(first);
|
||||
base = 22;
|
||||
}else {
|
||||
base = 10;
|
||||
}
|
||||
}else {
|
||||
error = FALSE;
|
||||
base = 8;
|
||||
if(!base) base = 8;
|
||||
}
|
||||
}else {
|
||||
base = 10;
|
||||
if(!base) base = 10;
|
||||
}
|
||||
digits[base] = 0;
|
||||
|
||||
if(sep) {
|
||||
groups_no = strlen(grouping)+2;
|
||||
groups = calloc(groups_no, sizeof(char));
|
||||
MSVCP_basic_string_char_ctor(&groups_found);
|
||||
if(found_zero) ++groups_no;
|
||||
}
|
||||
|
||||
for(; first->strbuf; istreambuf_iterator_wchar_inc(first)) {
|
||||
if(!(digits_pos = wcschr(digits, first->val))) {
|
||||
if(sep && first->val==sep) {
|
||||
if(cur_group == groups_no+1) {
|
||||
if(groups[1] != groups[2]) {
|
||||
error = TRUE;
|
||||
break;
|
||||
}else {
|
||||
memmove(groups+1, groups+2, groups_no);
|
||||
groups[cur_group] = 0;
|
||||
}
|
||||
}else {
|
||||
cur_group++;
|
||||
}
|
||||
if(!groups_no) break; /* empty group - stop parsing */
|
||||
MSVCP_basic_string_char_append_ch(&groups_found, groups_no);
|
||||
groups_no = 0;
|
||||
++cur_group;
|
||||
}else {
|
||||
break;
|
||||
}
|
||||
}else {
|
||||
error = FALSE;
|
||||
if(dest_empty && first->val == digits[0])
|
||||
if(dest_empty && first->val == digits[0]) {
|
||||
found_zero = TRUE;
|
||||
++groups_no;
|
||||
continue;
|
||||
}
|
||||
dest_empty = FALSE;
|
||||
/* skip digits that can't be copied to dest buffer, other
|
||||
* functions are responsible for detecting overflows */
|
||||
|
@ -4483,14 +4486,20 @@ static int num_get__Getifld(const num_get *this, char *dest, istreambuf_iterator
|
|||
*dest++ = (digits_pos-digits<10 ? '0'+digits_pos-digits :
|
||||
(digits_pos-digits<16 ? 'a'+digits_pos-digits-10 :
|
||||
'A'+digits_pos-digits-16));
|
||||
if(sep && groups[cur_group]<CHAR_MAX)
|
||||
groups[cur_group]++;
|
||||
if(sep && groups_no<CHAR_MAX)
|
||||
++groups_no;
|
||||
}
|
||||
}
|
||||
|
||||
if(sep && groups_no)
|
||||
MSVCP_basic_string_char_append_ch(&groups_found, groups_no);
|
||||
|
||||
groups = MSVCP_basic_string_char_c_str(&groups_found);
|
||||
if(cur_group && !groups[cur_group])
|
||||
error = TRUE;
|
||||
else if(!cur_group)
|
||||
{
|
||||
error = TRUE; /* trailing empty */
|
||||
found_zero = FALSE;
|
||||
}else if(!cur_group) /* no groups, skip loop */
|
||||
cur_group--;
|
||||
|
||||
for(; cur_group>=0 && !error; cur_group--) {
|
||||
|
@ -4506,12 +4515,17 @@ static int num_get__Getifld(const num_get *this, char *dest, istreambuf_iterator
|
|||
grouping++;
|
||||
}
|
||||
}
|
||||
MSVCP_basic_string_char_dtor(&grouping_bstr);
|
||||
free(groups);
|
||||
|
||||
if(error)
|
||||
dest = dest_beg;
|
||||
else if(dest_empty)
|
||||
MSVCP_basic_string_char_dtor(&grouping_bstr);
|
||||
if(sep)
|
||||
MSVCP_basic_string_char_dtor(&groups_found);
|
||||
|
||||
if(error) {
|
||||
if (found_zero)
|
||||
*dest++ = '0';
|
||||
else
|
||||
dest = dest_beg;
|
||||
}else if(dest_empty)
|
||||
*dest++ = '0';
|
||||
*dest = '\0';
|
||||
|
||||
|
@ -5470,10 +5484,11 @@ int __cdecl num_get_char__Getifld(const num_get *this, char *dest, istreambuf_it
|
|||
|
||||
numpunct_char *numpunct = numpunct_char_use_facet(loc);
|
||||
basic_string_char grouping_bstr;
|
||||
basic_string_char groups_found;
|
||||
int basefield, base, groups_no = 0, cur_group = 0;
|
||||
char *dest_beg = dest, *dest_end = dest+24, *groups = NULL, sep;
|
||||
const char *grouping;
|
||||
BOOL error = TRUE, dest_empty = TRUE;
|
||||
char *dest_beg = dest, *dest_end = dest+24, sep;
|
||||
const char *grouping, *groups;
|
||||
BOOL error = TRUE, dest_empty = TRUE, found_zero = FALSE;
|
||||
|
||||
TRACE("(%p %p %p %04x %p)\n", dest, first, last, fmtflags, loc);
|
||||
|
||||
|
@ -5497,58 +5512,68 @@ int __cdecl num_get_char__Getifld(const num_get *this, char *dest, istreambuf_it
|
|||
istreambuf_iterator_char_inc(first);
|
||||
}
|
||||
|
||||
if(!base && first->strbuf && first->val=='0') {
|
||||
if(first->strbuf && first->val=='0') {
|
||||
found_zero = TRUE;
|
||||
istreambuf_iterator_char_inc(first);
|
||||
if(first->strbuf && (first->val=='x' || first->val=='X')) {
|
||||
istreambuf_iterator_char_inc(first);
|
||||
base = 22;
|
||||
if(!base || base == 22) {
|
||||
found_zero = FALSE;
|
||||
istreambuf_iterator_char_inc(first);
|
||||
base = 22;
|
||||
}else {
|
||||
base = 10;
|
||||
}
|
||||
}else {
|
||||
error = FALSE;
|
||||
base = 8;
|
||||
if(!base) base = 8;
|
||||
}
|
||||
}else {
|
||||
base = 10;
|
||||
if (!base) base = 10;
|
||||
}
|
||||
|
||||
if(sep) {
|
||||
groups_no = strlen(grouping)+2;
|
||||
groups = calloc(groups_no, sizeof(char));
|
||||
if(sep)
|
||||
{
|
||||
MSVCP_basic_string_char_ctor(&groups_found);
|
||||
if(found_zero) ++groups_no;
|
||||
}
|
||||
|
||||
for(; first->strbuf; istreambuf_iterator_char_inc(first)) {
|
||||
if(!memchr(digits, first->val, base)) {
|
||||
if(sep && first->val==sep) {
|
||||
if(cur_group == groups_no+1) {
|
||||
if(groups[1] != groups[2]) {
|
||||
error = TRUE;
|
||||
break;
|
||||
}else {
|
||||
memmove(groups+1, groups+2, groups_no);
|
||||
groups[cur_group] = 0;
|
||||
}
|
||||
}else {
|
||||
cur_group++;
|
||||
}
|
||||
if(!groups_no) break; /* empty group - stop parsing */
|
||||
MSVCP_basic_string_char_append_ch(&groups_found, groups_no);
|
||||
groups_no = 0;
|
||||
++cur_group;
|
||||
}else {
|
||||
break;
|
||||
}
|
||||
}else {
|
||||
error = FALSE;
|
||||
if(dest_empty && first->val == '0')
|
||||
{
|
||||
found_zero = TRUE;
|
||||
++groups_no;
|
||||
continue;
|
||||
}
|
||||
dest_empty = FALSE;
|
||||
/* skip digits that can't be copied to dest buffer, other
|
||||
* functions are responsible for detecting overflows */
|
||||
if(dest < dest_end)
|
||||
*dest++ = first->val;
|
||||
if(sep && groups[cur_group]<CHAR_MAX)
|
||||
groups[cur_group]++;
|
||||
if(sep && groups_no<CHAR_MAX)
|
||||
++groups_no;
|
||||
}
|
||||
}
|
||||
|
||||
if(sep && groups_no)
|
||||
MSVCP_basic_string_char_append_ch(&groups_found, groups_no);
|
||||
|
||||
groups = MSVCP_basic_string_char_c_str(&groups_found);
|
||||
if(cur_group && !groups[cur_group])
|
||||
error = TRUE;
|
||||
else if(!cur_group)
|
||||
{
|
||||
error = TRUE; /* trailing empty */
|
||||
found_zero = FALSE;
|
||||
}else if(!cur_group) /* no groups, skip loop */
|
||||
cur_group--;
|
||||
|
||||
for(; cur_group>=0 && !error; cur_group--) {
|
||||
|
@ -5564,12 +5589,17 @@ int __cdecl num_get_char__Getifld(const num_get *this, char *dest, istreambuf_it
|
|||
grouping++;
|
||||
}
|
||||
}
|
||||
MSVCP_basic_string_char_dtor(&grouping_bstr);
|
||||
free(groups);
|
||||
|
||||
if(error)
|
||||
dest = dest_beg;
|
||||
else if(dest_empty)
|
||||
MSVCP_basic_string_char_dtor(&grouping_bstr);
|
||||
if(sep)
|
||||
MSVCP_basic_string_char_dtor(&groups_found);
|
||||
|
||||
if(error) {
|
||||
if (found_zero)
|
||||
*dest++ = '0';
|
||||
else
|
||||
dest = dest_beg;
|
||||
}else if(dest_empty)
|
||||
*dest++ = '0';
|
||||
*dest = '\0';
|
||||
|
||||
|
|
Loading…
Reference in New Issue