Opened 17 years ago

Closed 17 years ago

#515 closed Support Requests (Fixed)

VC7.1 boost_1_33_0 regex runtime assertion fail.

Reported by: mindaou Owned by: nobody
Milestone: Component: None
Version: None Severity:
Keywords: Cc:

Description

Hi,
   I am new in boost. I use boost_1_33_0 and VC7.1.
When I run the regex sample code(string split and
credit card number check), assertion failed. I dont
know how to solve it.

I build and install boost like this:
    bjam "-sTOOLS=vc-7_1" install

Then I set the include path and library path in VC7.1.
I can compile and build(debug mode) the program
successfully, but fail to execute it.

The assertion fail message is as following:

Assertion failed: r == 1 << 8, file
C:\boost_1_33_0\libs\regex\build\../src/w32_
regex_traits.cpp, line 108

------

    Then I tried using another boost library
"tokenizer". It works good. I think I install boost
properly. I just can't figure out why I can't use
regex. My VC7.1 environment settings are all default. I
tried  another VC6-built boost, and it has the same
assertion fail with my VC6. Can anyone help me with
this? Thank you.


Change History (7)

comment:1 by mindaou, 17 years ago

Summary: boost_1_33_0 regex runtime assertion fail.VC7.1 boost_1_33_0 regex runtime assertion fail.

comment:2 by John Maddock, 17 years ago

Logged In: YES 
user_id=14804

The assertion will fail if the windows API LCMapString has
failed for some reason.  This code is heavily tested on this
platform and I've never seen this before, so I'm assuming
that there is something about your machine or locale that's
causing the problem.  

So... can you please tell me which version of Windows you
are running and which locale the machine is using?

Can you also insert a call to GetLastError just before the
assertion that fails (after the call to LCMapString) so we
can find out why the failure is occuring?

Many thanks,

John Maddock.

comment:3 by mindaou, 17 years ago

Logged In: YES 
user_id=1380717

Thanks for your response.
I use Windows XP HOME SP2 Traditional Chinese Version.
I printed the locale in the program: cout.getloc().name()
It shows "C".

I made the following testing:
I used another machinese (Windows 2003 Enterprise English
ver.) to run my executable file. Surprisingly, it works!
Therefore, I think it's the locale problem you mentioned.
In my computer, the "Control Panel/Regional and Language
Options/Regional Options/Standards and formats" is
[CHINESE(TAIWAN)]. In that Windows 2003 machine it's
[ENGLISH(U.S.)].
So, I changed my computer setting to [ENGLISH(U.S.)], and
then, the program works on machine without any assertion
failure! 
With CHINESE setting, it assertion fails.
With ENGLISH setting, it works. 
This is my current status.

Besides, I inserted GetLastError() in your code. Like this:
--------------------------------------
int r = ::LCMapStringA(this->m_locale, LCMAP_LOWERCASE,
char_map, 1 << CHAR_BIT, this->m_lower_map, 1 << CHAR_BIT);
std::cout<<GetLastError()<<" "<<r;   
BOOST_ASSERT(r == 1 << CHAR_BIT);
--------------------------------------
When assertion fails, GetLastError()=122, r=240
When NO assertion fails, GetLastError()=122, r=256
   
Hope these information help.

mindaou

comment:4 by John Maddock, 17 years ago

Logged In: YES 
user_id=14804

Thanks for the information, can you change the final block
of code to read as shown below and see if that fixes the
problem?  If posible please run the regression tests by doing a:

cd libs/regex/test
bjam -sTOOLS=vc-7_1 test

Many thanks,  John Maddock.

And the code:

   //
   // fill in lower case map:
   //
   char char_map[1 << CHAR_BIT];
   for(int ii = 0; ii < (1 << CHAR_BIT); ++ii)
      char_map[ii] = static_cast<char>(ii);
   int r = ::LCMapStringA(this->m_locale, LCMAP_LOWERCASE,
char_map, 1 << CHAR_BIT, this->m_lower_map, 1 << CHAR_BIT);
   BOOST_ASSERT(r != 0);
   if(r < (1 << CHAR_BIT))
   {
      // if we have multibyte characters then not all may
have been given
      // a lower case mapping:
      for(int jj = r; jj < (1 << CHAR_BIT); ++jj)
         this->m_lower_map[jj] = static_cast<char>(jj);
   }
   r = ::GetStringTypeExA(this->m_locale, CT_CTYPE1,
char_map, 1 << CHAR_BIT, this->m_type_map);
   BOOST_ASSERT(0 != r);

comment:5 by mindaou, 17 years ago

Logged In: YES 
user_id=1380717

fixed! Good work~
Could you please explain what's the bug is?

mindaou

comment:6 by John Maddock, 17 years ago

Logged In: YES 
user_id=14804

Not completely:  My assumption was that LCMapString would
either fail completely (return 0) or provide lower case
mapping for all the characters requested.  Apparently it can
succeed by just providing *some* of the information
requested.  My guess is that upper/lower case mappings have
no meaning for characters above a certain value when using a
multibyte character set, so the fix is to set the identity
translation for all the characters that don't get translated
by LCMapString.  

One caveat: using a narrow character regular expression on a
multibyte character string is not actually a good idea,
unless you restrict yourself to ASCII characters,
Boost.Regex is *not* multibyte aware, no regex engines are
that I'm aware of.  If you really need that level of
internationalisation suppport then either use wide character
regexes or the new Unicode regexes (which support things
like UTF-8 if you need it).

BTW this fix may be too late for the 1.33.1 relese, but I'll
ask.

John.

comment:7 by John Maddock, 17 years ago

Status: assignedclosed
Note: See TracTickets for help on using tickets.