00001 #include "ctl/ctldef.h"
00002
00017 #ifndef CTL_UNIT
00018 #ifdef __GNUC__
00019
00025 size_t strnlen( const char* sz, size_t max )
00026 {
00027
00028 if( max == ~0u )
00029 return strlen(sz);
00030 {
00031 const char* psz = sz++;
00032 while( *psz++ && max-- )
00033 ;
00034 return psz-sz;
00035 }
00036 }
00037
00044 size_t wcsnlen( const wchar_t* sz, size_t max )
00045 {
00046
00047 if( max == ~0u )
00048 return wcslen(sz);
00049 {
00050 const wchar_t* psz = sz++;
00051 while( *psz++ && max-- )
00052 ;
00053 return psz-sz;
00054 }
00055 }
00056 #endif
00057
00058
00067 char* strnlabel( char* buff, const char* src, size_t buffSize )
00068 {
00069 char* ret = buff;
00070 if( !isalpha(*src) )
00071 {
00072
00073 *buff++ = '_';
00074 buffSize--;
00075 }
00076 while( *src && buffSize-- )
00077 {
00078 if( isspace(*src) )
00079 {
00080
00081 src++;
00082 }
00083 else if( !isalnum(*src) )
00084 {
00085
00086 *buff++ = '_';
00087 src++;
00088 }
00089 else
00090 {
00091 *buff++ = *src++;
00092 }
00093 }
00094 if( buffSize >= 0 )
00095 *buff = 0;
00096 return ret;
00097 }
00098
00106 char* strnupper( char* buff, const char* src, size_t buffSize )
00107 {
00108 char* ret = buff;
00109 while( *src && buffSize-- )
00110 *buff++ = (char)toupper(*src++);
00111 if( buffSize >= 0 )
00112 *buff = 0;
00113 return ret;
00114 }
00115
00123 char* strnlower( char* buff, const char* src, size_t buffSize )
00124 {
00125 char* ret = buff;
00126 while( *src && buffSize-- )
00127 *buff++ = (char)tolower(*src++);
00128 if( buffSize >= 0 )
00129 *buff = 0;
00130 return ret;
00131 }
00132
00141 wchar_t* wcsnlabel( wchar_t* buff, const wchar_t* src, size_t buffSize )
00142 {
00143 wchar_t* ret = buff;
00144 if( !cisalpha(wchar_t)(*src) )
00145 {
00146
00147 *buff++ = '_';
00148 buffSize--;
00149 }
00150 while( *src && buffSize-- )
00151 {
00152 if( cisspace(wchar_t)(*src) )
00153 {
00154
00155 src++;
00156 }
00157 if( !cisalnum(wchar_t)(*src) )
00158 {
00159
00160 *buff++ = '_';
00161 src++;
00162 }
00163 else
00164 {
00165 *buff++ = *src++;
00166 }
00167 }
00168 if( buffSize >= 0 )
00169 *buff = 0;
00170 return ret;
00171 }
00172
00180 wchar_t* wcsnupper( wchar_t* buff, const wchar_t* src, size_t buffSize )
00181 {
00182 wchar_t* ret = buff;
00183 while( *src && buffSize-- )
00184 *buff++ = ctoupper(wchar_t)(*src++);
00185 if( buffSize >= 0 )
00186 *buff = 0;
00187 return ret;
00188 }
00189
00197 wchar_t* wcsnlower( wchar_t* buff, const wchar_t* src, size_t buffSize )
00198 {
00199 wchar_t* ret = buff;
00200 while( *src && buffSize-- )
00201 *buff++ = ctolower(wchar_t)(*src++);
00202 if( buffSize >= 0 )
00203 *buff = 0;
00204 return ret;
00205 }
00206
00207 #ifdef __GNUC__
00208
00212 int wcsncasecmp( const wchar_t* sz1, const wchar_t* sz2, size_t max )
00213 {
00214 while( max-- )
00215 {
00216 int val = ctolower(wchar_t)(*sz1)-ctolower(wchar_t)(*sz2);
00217 if( val )
00218 return val;
00219 if( !*sz1 )
00220 break;
00221 sz1++;
00222 sz2++;
00223 }
00224 return 0;
00225 }
00226 double wcstod( const wchar_t* sz, wchar_t** ppsz )
00227 {
00228 double ret;
00229 char buff[64];
00230 int max = 64;
00231 char* pbuff = buff;
00232 const wchar_t* psz = sz;
00233 while( max-- && *psz )
00234 *pbuff++ = (char)*psz++;
00235 if( max >= 0 )
00236 *pbuff = 0;
00237 ret = strtod( buff, &pbuff );
00238 *ppsz = (wchar_t*)sz + (pbuff-buff);
00239 return ret;
00240 }
00241 long wcstol( const wchar_t* sz, wchar_t** psz, int radix )
00242 {
00243 long ret = 0;
00244 bool bneg = false;
00245 while( *sz && cisspace(wchar_t)(*sz) )
00246 sz++;
00247 if( *sz == '-' )
00248 {
00249 bneg = true;
00250 psz++;
00251 }
00252 while( *sz )
00253 {
00254 int digit;
00255 if( radix > 10 && *sz > 'a' )
00256 digit = 10 + *sz - 'a';
00257 else if( radix > 10 && *sz > 'A' )
00258 digit = 10 + *sz - 'A';
00259 else if( *sz-'0' < radix )
00260 digit = *sz-'0';
00261 else break;
00262 ret *= radix;
00263 ret += digit;
00264 sz++;
00265 }
00266 if( bneg )
00267 ret = -ret;
00268 *psz = (wchar_t*)sz;
00269 return ret;
00270 }
00271
00272 #endif
00273
00274 #else
00275 #include "unit/unit.h"
00276 #include <math.h>
00277
00278 void spew(void);
00279
00280 #if 1
00281
00288 void Test_strings(void)
00289 {
00290 #define MFG_TestStrings(tchar)\
00291 {\
00292 const tchar* const sz = szconst(tchar,"I could have been your daddy.");\
00293 Test_Error( cstrnlen(tchar)(sz,~0u) == cstrlen(tchar)(sz) );\
00294 Test_Error( cstrnlen(tchar)(sz,4) == 4 );\
00295 }
00296 MFG_TestStrings(char);
00297 MFG_TestStrings(wchar_t);
00298 }
00299
00306 void Test_sconst(void)
00307 {
00308
00309 #define MFG_TestStrCmps(tchar) \
00310 {\
00311 const tchar* const sz = szconst(tchar,"All I ever wanted was a Pepsi.");\
00312 ctl_sconst_auto_sz(tchar, sz, test1 );\
00313 ctl_sconst(tchar) strptst = test1;\
00314 Test_Error( !ctl_sconst_strcmp(tchar, &test1, sz ) );\
00315 Test_Error( !ctl_sconst_stricmp(tchar, &test1, sz ) );\
00316 Test_Error( ctl_sconst_strchr(tchar, &test1, chconst(tchar,'I') ) );\
00317 Test_Error( ctl_sconst_parse(tchar, &test1 ) == sz + 4 );\
00318 Test_Error( ctl_sconst_strichr(tchar, &test1, chconst(tchar,'V') ) );\
00319 Test_Error( ctl_sconst_parse(tchar, &test1 ) == sz + 7 );\
00320 Test_Error( ctl_sconst_strstr(tchar, &test1, szconst(tchar,"was") ) );\
00321 Test_Error( ctl_sconst_parse(tchar, &test1 ) == sz + 18 );\
00322 Test_Error( ctl_sconst_stristr(tchar, &test1, szconst(tchar,"pepsi") ) );\
00323 Test_Error( ctl_sconst_parse(tchar, &test1 ) == sz + 24 );\
00324 Test_Error( ctl_sconst_strpbrk(tchar, &strptst, szconst(tchar,"cab") ) );\
00325 Test_Error( ctl_sconst_parse(tchar, &strptst ) == sz + 12 );\
00326 }
00327 MFG_TestStrCmps(char);
00328 MFG_TestStrCmps(wchar_t);
00329
00330 #define MFG_TestSpaceWalks(tchar)\
00331 {\
00332 const tchar* const sz = szconst(tchar," a bb ccc X yy zzz");\
00333 ctl_sconst_auto_sz(tchar, sz, strTestSpace );\
00334 Test_Error( ctl_sconst_skipspace(tchar, &strTestSpace ) );\
00335 Test_Error( ctl_sconst_strchr(tchar, &strTestSpace, chconst(tchar,'a') ) );\
00336 Test_Error( ctl_sconst_nextspace(tchar, &strTestSpace ) );\
00337 Test_Error( ctl_sconst_skipspace(tchar, &strTestSpace ) );\
00338 Test_Error( !ctl_sconst_strncmp(tchar, &strTestSpace, szconst(tchar,"bb"), 2 ) );\
00339 Test_Error( ctl_sconst_nextspace(tchar, &strTestSpace ) );\
00340 Test_Error( ctl_sconst_skipspace(tchar, &strTestSpace ) );\
00341 Test_Error( !ctl_sconst_strncmp(tchar, &strTestSpace, szconst(tchar,"ccc"), 3 ) );\
00342 Test_Error( ctl_sconst_nextspace(tchar, &strTestSpace ) );\
00343 Test_Error( ctl_sconst_skipspace(tchar, &strTestSpace ) );\
00344 Test_Error( ctl_sconst_strchr(tchar, &strTestSpace, chconst(tchar,'X') ) );\
00345 Test_Error( ctl_sconst_nextspace(tchar, &strTestSpace ) );\
00346 Test_Error( ctl_sconst_skipspace(tchar, &strTestSpace ) );\
00347 Test_Error( !ctl_sconst_strncmp(tchar, &strTestSpace, szconst(tchar,"yy"), 2 ) );\
00348 Test_Error( ctl_sconst_nextspace(tchar, &strTestSpace ) );\
00349 Test_Error( ctl_sconst_skipspace(tchar, &strTestSpace ) );\
00350 Test_Error( !ctl_sconst_strncmp(tchar, &strTestSpace, szconst(tchar,"zzz"), 3 ) );\
00351 }
00352 MFG_TestSpaceWalks(char);
00353 MFG_TestSpaceWalks(wchar_t);
00354
00355
00356 #define MFG_Dmatch(tchar)\
00357 {\
00358 const tchar* const sz = szconst(tchar,"{ a { b { c } } }");\
00359 ctl_sconst_auto_sz(tchar, sz, test );\
00360 ctl_sconst(tchar) a, b, c, tmp;\
00361 Test_Error( ctl_sconst_dmatch(tchar, &test, &a, chconst(tchar,'{'), chconst(tchar,'}') ) );\
00362 tmp = a;\
00363 Test_Error( ctl_sconst_dmatch(tchar, &tmp, &b, chconst(tchar,'{'), chconst(tchar,'}') ) );\
00364 tmp = b;\
00365 Test_Error( ctl_sconst_dmatch(tchar, &tmp, &c, chconst(tchar,'{'), chconst(tchar,'}') ) );\
00366 Test_Error( ctl_sconst_skipspace(tchar, &c ) );\
00367 Test_Error( ctl_sconst_skipspace(tchar, &b ) );\
00368 Test_Error( ctl_sconst_skipspace(tchar, &a ) );\
00369 Test_Error( *ctl_sconst_parse(tchar, &a ) == chconst(tchar,'a') );\
00370 Test_Error( *ctl_sconst_parse(tchar, &b ) == chconst(tchar,'b') );\
00371 Test_Error( *ctl_sconst_parse(tchar, &c ) == chconst(tchar,'c') );\
00372 }
00373 MFG_Dmatch(char);
00374 MFG_Dmatch(wchar_t);
00375
00376
00377 #define MFG_Dmatchstr(tchar)\
00378 {\
00379 const tchar* const sz = szconst(tchar,"begin a begin b begin c end end end");\
00380 ctl_sconst_auto_sz(tchar, sz, test );\
00381 ctl_sconst(tchar) a, b, c, tmp;\
00382 Test_Error( ctl_sconst_dmatchstr(tchar, &test, &a, szconst(tchar,"begin"), szconst(tchar,"end") ) );\
00383 tmp = a;\
00384 Test_Error( ctl_sconst_dmatchstr(tchar, &tmp, &b, szconst(tchar,"begin"), szconst(tchar,"end") ) );\
00385 tmp = b;\
00386 Test_Error( ctl_sconst_dmatchstr(tchar, &tmp, &c, szconst(tchar,"begin"), szconst(tchar,"end") ) );\
00387 Test_Error( ctl_sconst_skipspace(tchar, &c ) );\
00388 Test_Error( ctl_sconst_skipspace(tchar, &b ) );\
00389 Test_Error( ctl_sconst_skipspace(tchar, &a ) );\
00390 Test_Error( *ctl_sconst_parse(tchar, &a ) == chconst(tchar,'a') );\
00391 Test_Error( *ctl_sconst_parse(tchar, &b ) == chconst(tchar,'b') );\
00392 Test_Error( *ctl_sconst_parse(tchar, &c ) == chconst(tchar,'c') );\
00393 }
00394 MFG_Dmatchstr(char);
00395 MFG_Dmatchstr(wchar_t);
00396
00397
00398 #define on 1
00399 #define off 0
00400 #define yes 1
00401 #define no 0
00402 #define TestList(def,tchar) \
00403 def(tchar, Equal, bool, false ) \
00404 def(tchar, Equal, bool, 1 ) \
00405 def(tchar, Equal, bool, true ) \
00406 def(tchar, Equal, bool, 0 ) \
00407 def(tchar, Equal, bool, yes ) \
00408 def(tchar, Equal, bool, off ) \
00409 def(tchar, Equal, bool, no ) \
00410 def(tchar, Equal, bool, on ) \
00411 def(tchar, Equal, int8, 127 ) \
00412 def(tchar, Equal, int8, -127 ) \
00413 def(tchar, Equal, uint8, 255 ) \
00414 def(tchar, Equal, uint8, 42 ) \
00415 def(tchar, Equal, int16, -1000 ) \
00416 def(tchar, Equal, int16, -32767 ) \
00417 def(tchar, Equal, uint16, 65535 ) \
00418 def(tchar, Equal, uint16, 2011 ) \
00419 def(tchar, Equal, int32, -100001000 ) \
00420 def(tchar, Equal, int32, -2000010000 ) \
00421 def(tchar, Equal, uint32, 1110204398 ) \
00422 def(tchar, Equal, uint32, 1000010000 ) \
00423 def(tchar, Equal, int64, -1000101000 ) \
00424 def(tchar, Equal, uint64, 1234567890 )\
00425 def(tchar, Nearly, float32, 3.543 ) \
00426 def(tchar, Nearly, float64, 9999.123 )
00427 #define Equal(v1,v2) ((v1)==(v2))
00428 #define Nearly(v1,v2) (fabs((v1)-(v2)) <= float64_compare_epsilon)
00429 #define XDEFSTR( tchar, howclose, type, value ) szconst(tchar,#value) szconst(tchar," ")
00430 #define XDEFTEST( tchar, howclose, type, value ) \
00431 {\
00432 type tval = 0;\
00433 Test_Error( ppConcat(ctl_sconst_get,type)( tchar, &test, &tval ) );\
00434 \
00435 Test_Named( "ctl_sconst_get" #type " ", howclose ( tval, value ) );\
00436 }
00437 #define MFG_StrToxxx(tchar)\
00438 {\
00439 const tchar* const sz = TestList(XDEFSTR,tchar);\
00440 ctl_sconst_auto_sz(tchar, sz, test );\
00441 TestList(XDEFTEST,tchar);\
00442 }
00443 MFG_StrToxxx(char);
00444 MFG_StrToxxx(wchar_t);
00445 #undef TestList
00446 #undef XDEFSTR
00447 #undef XDEFTEST
00448 #undef MFG_StrToxxx
00449
00450
00451 #define TestXList1(def,tchar) \
00452 def(tchar, uint8, 42 ) \
00453 def(tchar, uint16, abcd ) \
00454 def(tchar, uint32, c05acbde ) \
00455 def(tchar, uint64, ff8e9dacbbcad9e8 )\
00456 def(tchar, int8, 42 ) \
00457 def(tchar, int16, 7bcd ) \
00458 def(tchar, int32, 605acbde ) \
00459 def(tchar, int64, 7f8e9dacbbcad9e8 )
00460 #define XDEFSTR( tchar, type, value ) szconst(tchar,#value) szconst(tchar," ")
00461 #define XDEFTEST( tchar, type, value ) \
00462 {\
00463 type tval = 0;\
00464 Test_Error( ppConcat(ctl_sconst_getx,type)( tchar, &test, &tval ) );\
00465 Test_Named( "ctl_sconst_get" #type " ", (uint64)tval == uint64const(ppConcat(0x,value)) );\
00466 }
00467 #define MFG_XTests(tchar)\
00468 {\
00469 const tchar* const sz = TestXList1(XDEFSTR,tchar);\
00470 ctl_sconst_auto_sz(tchar, sz, test );\
00471 TestXList1(XDEFTEST,tchar);\
00472 }
00473 MFG_XTests(char);
00474 MFG_XTests(wchar_t);
00475 #undef TestXList1
00476 #undef XDEFSTR
00477 #undef XDEFTEST
00478 #undef MFG_XTests
00479
00480
00481 #define MFG_FindClassTests(tchar)\
00482 {\
00483 const tchar* const sz = szconst(tchar," ! 3 z f");\
00484 ctl_sconst_auto_sz(tchar, sz, test );\
00485 Test_Error( ctl_sconst_findclass(tchar, &test, ispunct ) );\
00486 Test_Error( *ctl_sconst_parse(tchar, &test ) == chconst(tchar,'!') );\
00487 Test_Error( ctl_sconst_findclass(tchar, &test, isdigit ) );\
00488 Test_Error( *ctl_sconst_parse(tchar, &test ) == chconst(tchar,'3') );\
00489 ctl_sconst_reset(tchar, &test );\
00490 Test_Error( ctl_sconst_findclass(tchar, &test, isalpha ) );\
00491 Test_Error( *ctl_sconst_parse(tchar, &test ) == chconst(tchar,'z') );\
00492 Test_Error( ctl_sconst_findclass(tchar, &test, isxdigit ) );\
00493 Test_Error( *ctl_sconst_parse(tchar, &test ) == chconst(tchar,'f') );\
00494 }
00495 MFG_FindClassTests(char);
00496 MFG_FindClassTests(wchar_t);
00497 }
00498
00505 void Test_mstring(void)
00506 {
00507
00508 #define Test1(tchar)\
00509 {\
00510 const tchar testval[] = szconst(tchar,"All I ever wanted was a Pepsi. Institutionalized. Oohgah");\
00511 ctl_gstring_auto(tchar, testing );\
00512 ctl_gstring_sprintf(tchar, (&testing, szconst(tchar,"All I ever wanted was a %") szstrfmt(tchar) szconst(tchar,"."), szconst(tchar,"Pepsi") ) );\
00513 ctl_gstring_strcat(tchar, &testing, szconst(tchar," Institutionalized.") );\
00514 ctl_gstring_strncat(tchar, &testing, szconst(tchar," Oohgah-boogah"), 8 );\
00515 Test_Error( 0 == cstrcmp(tchar)( testing.begin, testval ) );\
00516 ctl_gstring_destroy(tchar, &testing );\
00517 }
00518 Test1(char);
00519 Test1(wchar_t)
00520 #undef Test1
00521
00522
00523 #define Test2(tchar)\
00524 {\
00525 const tchar testval[] = szconst(tchar,"All I ever wanted was a Pepsi. Institutionalized. Oohgah");\
00526 ctl_fstring_auto(tchar, 128, testing );\
00527 ctl_fstring_sprintf(tchar, (&testing, szconst(tchar,"All I ever wanted was a %") szstrfmt(tchar) szconst(tchar,"."), szconst(tchar,"Pepsi") ) );\
00528 ctl_fstring_strcat(tchar, &testing, szconst(tchar," Institutionalized.") );\
00529 ctl_fstring_strncat(tchar, &testing, szconst(tchar," Oohgah-boogah"), 8 );\
00530 Test_Error( 0 == cstrcmp(tchar)( testing.begin, testval ) );\
00531 }
00532 Test2(char);
00533 Test2(wchar_t)
00534 #undef Test2
00535
00536
00537 #define Test3(tchar)\
00538 {\
00539 const tchar testval[] = szconst(tchar,"All I ever wanted was a Pepsi. ");\
00540 ctl_fstring_auto(tchar, 32, testing );\
00541 ctl_fstring_sprintf(tchar, (&testing, szconst(tchar,"All I ever wanted was a %") szstrfmt(tchar) szconst(tchar,"."), szconst(tchar,"Pepsi") ) );\
00542 ctl_fstring_strcat(tchar, &testing, szconst(tchar," Institutionalized.") );\
00543 ctl_fstring_strncat(tchar, &testing, szconst(tchar," Oohgah-boogah"), 8 );\
00544 Test_Error( 0 == cstrcmp(tchar)(testing.begin, testval ) );\
00545 }
00546 Test3(char);
00547 Test3(wchar_t)
00548 #undef Test3
00549
00550
00551 #define TestList(tchar,def) \
00552 def(tchar, Equal, bool, false ) \
00553 def(tchar, Equal, bool, true ) \
00554 def(tchar, Equal, int8, 127 ) \
00555 def(tchar, Equal, int8, -127 ) \
00556 def(tchar, Equal, uint8, 255 ) \
00557 def(tchar, Equal, uint8, 42 ) \
00558 def(tchar, Equal, int16, -1000 ) \
00559 def(tchar, Equal, int16, -32767 ) \
00560 def(tchar, Equal, uint16, 65535 ) \
00561 def(tchar, Equal, uint16, 2011 ) \
00562 def(tchar, Equal, int32, -100001000 ) \
00563 def(tchar, Equal, int32, -2000010000 ) \
00564 def(tchar, Equal, uint32, 1110204398 ) \
00565 def(tchar, Equal, uint32, 1000010000 ) \
00566 def(tchar, Equal, int64, -1000101000 ) \
00567 def(tchar, Equal, uint64, 1234567890 )\
00568 def(tchar, Nearly, float32, 3.543 ) \
00569 def(tchar, Nearly, float64, 9999.123 )
00570 #define Equal(v1,v2) ((v1)==(v2))
00571 #define Nearly(v1,v2) (fabs((v1)-(v2)) <= float64_compare_epsilon)
00572 #define XDEFPUT( tchar, howclose, type, value ) \
00573 {\
00574 ppConcat(ctl_gstring_put,type)(tchar, &testing, value);\
00575 ctl_assertmem(testing.begin);\
00576 ctl_gstring_add(tchar, &testing, chconst(tchar,' ') );\
00577 ctl_assertmem(testing.begin);\
00578 }
00579 #define XDEFTEST( tchar, howclose, type, value ) \
00580 {\
00581 type tval = 0;\
00582 Test_Error( ppConcat(ctl_sconst_get,type)(tchar, &test, &tval ) );\
00583 Test_Named( "ctl_sconst_get" #type " ", howclose( tval, value ) );\
00584 }
00585 #define MFG_StrToxxx(tchar)\
00586 {\
00587 ctl_gstring_auto(tchar, testing );\
00588 TestList(tchar,XDEFPUT);\
00589 \
00590 {\
00591 ctl_sconst_auto_string(tchar, &testing, test );\
00592 TestList(tchar,XDEFTEST);\
00593 }\
00594 ctl_gstring_destroy(tchar, &testing );\
00595 }
00596 MFG_StrToxxx(char);
00597 MFG_StrToxxx(wchar_t);
00598 #undef TestList
00599 #undef XDEFPUT
00600 #undef XDEFTEST
00601 #undef MFG_StrToxxx
00602 }
00603
00604 #else
00605
00606
00607 #endif
00608
00609
00610 #endif
00611