Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:49:21

0001 /*
0002  * Copyright (c) 2019 Opticks Team. All Rights Reserved.
0003  *
0004  * This file is part of Opticks
0005  * (see https://bitbucket.org/simoncblyth/opticks).
0006  *
0007  * Licensed under the Apache License, Version 2.0 (the "License"); 
0008  * you may not use this file except in compliance with the License.  
0009  * You may obtain a copy of the License at
0010  *
0011  *   http://www.apache.org/licenses/LICENSE-2.0
0012  *
0013  * Unless required by applicable law or agreed to in writing, software 
0014  * distributed under the License is distributed on an "AS IS" BASIS, 
0015  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
0016  * See the License for the specific language governing permissions and 
0017  * limitations under the License.
0018  */
0019 
0020 // om-;TEST=SStrTest om-t 
0021 
0022 #include <cassert>
0023 #include <csignal>
0024 #include <string>
0025 #include <iostream>
0026 #include <iomanip>
0027 
0028 #include "SStr.hh"
0029 #include "SPath.hh"
0030 
0031 #include "OPTICKS_LOG.hh"
0032 
0033 
0034 void test_ToULL()
0035 {
0036     char* s = new char[8+1] ; 
0037     s[0] = '\1' ; 
0038     s[1] = '\2' ; 
0039     s[2] = '\3' ; 
0040     s[3] = '\4' ; 
0041     s[4] = '\5' ; 
0042     s[5] = '\6' ; 
0043     s[6] = '\7' ; 
0044     s[7] = '\7' ; 
0045     s[8] = '\0' ; 
0046     
0047     typedef unsigned long long ULL ; 
0048 
0049     ULL v = SStr::ToULL(s ); 
0050 
0051     LOG(info) << " v " << std::hex << v ;
0052 
0053     assert( 0x707060504030201ull == v );
0054 }
0055 
0056 void test_FromULL()
0057 {
0058     typedef unsigned long long ULL ; 
0059     const char* s0 = "0123456789" ; 
0060     ULL v = SStr::ToULL(s0); 
0061 
0062     const char* s1 = SStr::FromULL( v ); 
0063     LOG(info) 
0064         << " s0 " << std::setw(16) << s0 
0065         << " s1 " << std::setw(16) << s1   
0066         ;
0067 
0068     ULL v0 = SStr::ToULL(NULL) ; 
0069     bool v0_expect = v0 == 0ull ;
0070     assert( v0_expect); 
0071     if(!v0_expect) std::raise(SIGINT); 
0072 
0073 }
0074 
0075 
0076 
0077 
0078 void test_Format1()
0079 {
0080     const char* fmt = "hello %s hello"  ; 
0081     const char* value = "world" ; 
0082     const char* result = SStr::Format1<256>(fmt, value );
0083     const char* expect = "hello world hello" ; 
0084 
0085     bool result_expect = strcmp( result, expect) == 0 ;
0086     assert(result_expect ); 
0087     if(!result_expect) std::raise(SIGINT); 
0088 
0089     // this asserts from truncation 
0090     //const char* result2 = SStr::Format1<16>(fmt, value );
0091     //LOG(info) << " result2 " << result2 ;  
0092  
0093 }
0094 
0095 
0096 void test_FormatInt()
0097 {
0098     const char* fmt = "/tmp/Frame%0.3d.ppm"   ; 
0099     LOG(info) << fmt ; 
0100     for(int i=-10 ; i < 10 ; i++ )
0101     {
0102         const char* result = SStr::FormatInt<64>(fmt, i );
0103         std::cout << result << std::endl ;   
0104     }
0105 }
0106 
0107 
0108 
0109 
0110 
0111 void test_FormatInt_2()
0112 {
0113     const char* fmt = "%d"   ; 
0114     LOG(info) << fmt ; 
0115     for(int i=-10 ; i < 10 ; i++ )
0116     {
0117         const char* result = SStr::FormatInt<8>(fmt, i );
0118         std::cout << result << std::endl ;   
0119     }
0120 }
0121 
0122 
0123 void test_FormatIndex()
0124 {
0125     for(int i=-10 ; i <= 10 ; i++ )
0126     {
0127         const char* result = SStr::FormatIndex(i);
0128         std::cout << " i " << std::setw(4) << i << "[" << result << "]" << std::endl ;   
0129     }
0130 }
0131 
0132 
0133 
0134 
0135 void test_Contains()
0136 {
0137     const char* s = "/hello/there/Cathode/World" ; 
0138 
0139     bool expect = SStr::Contains(s, "Cathode") == true && SStr::Contains(s, "cathode") == false  ;
0140     assert( expect ); 
0141     if(!expect) std::raise(SIGINT); 
0142 }
0143 void test_EndsWith()
0144 {
0145     const char* s = "/hello/there/Cathode/World" ; 
0146     bool expect = SStr::EndsWith(s, "Cathode") == false && SStr::EndsWith(s, "World") == true  ;
0147     assert( expect ); 
0148     if(!expect) std::raise(SIGINT); 
0149 }
0150 
0151 void test_StartsWith()
0152 {
0153     const char* s = "/hello/there/Cathode/World" ; 
0154     bool expect = SStr::StartsWith(s, "/hello") == true && SStr::StartsWith(s, "World") == false ;
0155     assert( expect ); 
0156     if(!expect) std::raise(SIGINT); 
0157 }
0158 
0159 
0160 
0161 
0162 
0163 void test_HasPointerSuffix()
0164 {
0165 
0166     std::vector<std::string> yes = 
0167       {
0168          "det0x110d9a820",
0169          "0x110d9a820" ,
0170          "0xdeadbeef0" 
0171       }
0172    ;
0173 
0174     std::vector<std::string> no = 
0175       {
0176          "tooshort",
0177          "0xdeadbeef",
0178          "0xdeadbeef"
0179       }
0180    ;
0181 
0182     for( unsigned i=0 ; i < yes.size() ; i++) 
0183     {
0184         std::cout << "y: " << yes[i] << std::endl ; 
0185         assert( SStr::HasPointerSuffix(yes[i].c_str(), 9) == true );
0186     }
0187     for( unsigned i=0 ; i < no.size() ; i++) 
0188     { 
0189         std::cout << "n: " << no[i] << std::endl ; 
0190         assert( SStr::HasPointerSuffix(no[i].c_str(), 9) == false );
0191     }
0192 
0193 }
0194 
0195 
0196 void test_HasPointerSuffix2()
0197 {
0198     const char* name = "World0x7fc10641cbb0" ; 
0199     bool expect = SStr::HasPointerSuffix( name, 9, 12 ) == true ;
0200     assert(expect) ; 
0201     if(!expect) std::raise(SIGINT) ; 
0202 
0203     assert( SStr::GetPointerSuffixDigits("World0x7fc10641cbb0") == 12 ); 
0204     assert( SStr::GetPointerSuffixDigits("World0x7fc10641cbb") == 11 ); 
0205     assert( SStr::GetPointerSuffixDigits("World0x7fc10641cb") == 10 ); 
0206     assert( SStr::GetPointerSuffixDigits("World0x7fc10641c") == 9 ); 
0207     assert( SStr::GetPointerSuffixDigits("World0x7fc10641") == 8 ); 
0208     assert( SStr::GetPointerSuffixDigits("World0x7fc1064") == 7 ); 
0209     assert( SStr::GetPointerSuffixDigits("World0x7fc106") == 6 ); 
0210     assert( SStr::GetPointerSuffixDigits("World0x7fc10") == 5 ); 
0211     assert( SStr::GetPointerSuffixDigits("World0x7fc1") == 4 ); 
0212     assert( SStr::GetPointerSuffixDigits("World0x7fc") == 3 ); 
0213     assert( SStr::GetPointerSuffixDigits("World0x7f") == 2 ); 
0214     assert( SStr::GetPointerSuffixDigits("World0x7") == 1 ); 
0215     assert( SStr::GetPointerSuffixDigits("World0x") == 0 ); 
0216     assert( SStr::GetPointerSuffixDigits("World0") == -1 ); 
0217     assert( SStr::GetPointerSuffixDigits("World") == -1 ); 
0218     assert( SStr::GetPointerSuffixDigits("") == -1 ); 
0219     assert( SStr::GetPointerSuffixDigits(NULL) == -1 ); 
0220 }
0221 
0222 
0223 void test_Replace()
0224 {
0225     const char* name = "TITAN RTX " ; 
0226     const char* xname2 = "TITAN_RTX_" ; 
0227     const char* name2 = SStr::Replace(name, ' ', '_' ); 
0228 
0229     bool expect = strcmp(name2, xname2) == 0 ;
0230     assert(expect);  
0231     if(!expect) std::raise(SIGINT) ; 
0232 }
0233 
0234 void test_ReplaceEnd()
0235 {
0236     const char* name = "/some/path/to/hello.ppm" ; 
0237     const char* xname2 = "/some/path/to/hello.npy" ; 
0238     const char* name2 = SStr::ReplaceEnd(name, ".ppm", ".npy" ); 
0239     bool expect = strcmp(name2, xname2) == 0 ;
0240     assert(expect);  
0241     if(!expect) std::raise(SIGINT) ; 
0242 }
0243 
0244 void test_ArrayToString()
0245 {
0246     // thinking about optix7c- and embedded_ptx_code from bin2c 
0247     // observe that without NULL termination get garbage on the end of the string 
0248     // which is why must use "--padd 0" which sets trailing bytes::
0249     // 
0250     //       bin2c --name data_variable_name --padd 0 inputfile > data.c 
0251     //
0252     const char imageBytes[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x00 } ; 
0253     std::string s = imageBytes ; 
0254     std::cout << "[" << s << "]" << std::endl ; 
0255     assert( s.compare("ABCDEF") == 0 ); 
0256     assert( 'A' == 0x41 ); 
0257 }
0258 
0259 
0260 
0261 
0262 
0263 void test_Save()
0264 {
0265     std::vector<std::string> v = { "red", "green", "blue", "cyan", "magenta", "yellow", "green" } ; 
0266     const char* path = "$TMP/SStrTest_test_Save.txt" ; 
0267     SStr::Save(path, v ); 
0268 }
0269 
0270 
0271 void test_LoadList()
0272 {
0273     std::vector<std::string> v0 = { "red", "green", "blue", "cyan", "magenta", "yellow", "green" } ; 
0274     
0275     const char* path = SPath::Resolve("$TMP/SStrTest/test_LoadList.txt", FILEPATH) ; 
0276     SStr::Save(path, v0 ); 
0277 
0278     std::vector<std::string> v1 ;    
0279     SStr::LoadList(path, v1 ); 
0280     assert( v0.size() == v1.size() ); 
0281 
0282 
0283     std::vector<std::string>* v2p = SStr::LoadList(path);  
0284     assert( v2p ); 
0285     const std::vector<std::string>& v2 = *v2p ; 
0286 
0287     assert( v2.size() == v0.size() ); 
0288 
0289 
0290     for( unsigned i=0 ; i < v0.size() ; i++) 
0291          std::cout 
0292              << std::setw(20) << v0[i] 
0293              << " : " 
0294              << std::setw(20) << v1[i] 
0295              << " : " 
0296              << std::setw(20) << v2[i] 
0297              << " : " 
0298              << std::endl
0299              ; 
0300 }
0301 
0302 
0303 
0304 
0305 
0306 
0307 
0308 
0309 
0310 const char* TXT = R"LITERAL(
0311 red
0312 green
0313 blue
0314 cyan
0315 magenta
0316 yellow
0317 )LITERAL" ; 
0318 
0319 void test_Save_Load()
0320 {
0321     const char* path = "$TMP/SStrTest/test_Save_Load.txt" ; 
0322     SStr::Save(path, TXT );
0323 
0324     const char* txt = SStr::Load(path); 
0325 
0326     LOG(info) << " TXT [" << TXT << "]"  ; 
0327     LOG(info) << " txt [" << txt << "]"  ; 
0328 
0329     assert( strcmp(txt, TXT) == 0 );  
0330 }
0331 
0332 void test_Save_PWD()
0333 {
0334     const char* path = "test_Save_PWD.txt" ; 
0335     SStr::Save(path, TXT );  
0336 }
0337 
0338 
0339 
0340 
0341 void test_Split()
0342 {
0343     std::vector<std::string> elem ; 
0344     const char* str = "red,green,blue,cyan,magenta,yellow" ; 
0345     SStr::Split(str, ',', elem ); 
0346     assert( elem.size() == 6 ); 
0347     for(int i=0 ; i < int(elem.size()) ; i++) std::cout << elem[i] << std::endl ; 
0348 }
0349 
0350 
0351 void test_Concat_()
0352 {
0353     std::cout << SStr::Concat_("hello/", 1, ".npy" ) << std::endl ; 
0354 }
0355 
0356 
0357 void test_AsInt()
0358 {
0359     const char* arg = "00000" ; 
0360     int i = SStr::AsInt(arg); 
0361     bool i_expect = i == 0 ;
0362     assert( i_expect ); 
0363     if(!i_expect) std::raise(SIGINT); 
0364 }
0365 
0366 
0367 void test_ExtractInt()
0368 {
0369     const char* path = "/some/long/path/with_00000.jpg" ; 
0370     int i = SStr::ExtractInt(path, -9, 5 ); 
0371     std::cout << "path " << path << " i " << i << std::endl ;  
0372     assert( i == 0 ); 
0373 }
0374 
0375 void test_SimpleMatch_WildMatch()
0376 {
0377     std::vector<std::string> labels = {
0378         "r0",
0379         "r1",
0380         "r2",
0381         "r3",
0382         "r1p0","r1p1","r1p2","r1p3",
0383         "r2p0","r2p1","r2p2","r2p3",
0384         "R3P0N0",
0385         "R3P0N1",
0386         "R3P0N2",
0387         "R3P1N0",
0388         "R3P1N1",
0389         "R3P1N2",
0390         "R3P1N3",
0391     }; 
0392    
0393     std::vector<std::string> querys = { 
0394          "r2", 
0395          "r2$", 
0396          "r2p", 
0397          "r2p$", 
0398          "r2p2$", 
0399          "R3P1", 
0400          "R3P1*", 
0401          "R3P1N", 
0402          "R3P1N?", 
0403          "R3P1N2$", 
0404          "R3P?N0", 
0405          "R3P1*", 
0406       } ; 
0407 
0408     for(int i=0 ; i < int(querys.size()) ; i++)
0409     {
0410         const char* q = querys[i].c_str() ;   
0411         unsigned lq = strlen(q); 
0412         bool qed = q[lq-1] == '$' ;
0413 
0414         std::cout 
0415             << " q " << q 
0416             << " lq " << lq 
0417             << " qed: " << ( qed ? "Y" : "N" )
0418             << std::endl 
0419             ;
0420 
0421 
0422         for(int j=0 ; j < int(labels.size()) ; j++)
0423         {
0424             const char* s = labels[j].c_str(); 
0425             bool sm = SStr::SimpleMatch(s,q); 
0426             bool wm = SStr::Match(s,q); 
0427             std::cout 
0428                 << " SStr::SimpleMatch(" 
0429                 << std::setw(7) << s 
0430                 << " , "
0431                 << std::setw(7) << q 
0432                 << " )  : "
0433                 << ( sm ? "Y" : " " )
0434                 ;
0435 
0436             std::cout 
0437                 << " SStr::Match(" 
0438                 << std::setw(7) << s 
0439                 << " , "
0440                 << std::setw(7) << q 
0441                 << " )  : "
0442                 << ( wm ? "Y" : " " )
0443                 ;
0444 
0445            std::cout << std::endl ; 
0446            
0447 
0448 
0449 
0450         }
0451     }
0452 }
0453 
0454 
0455 void test_ISplit()
0456 {
0457     LOG(info); 
0458 
0459     {
0460         const char* wavelength = "380,400,420,440,460" ; 
0461         std::vector<int> inm ; 
0462         SStr::ISplit(wavelength, inm, ',' ); 
0463         assert( inm.size() == 5 ); 
0464         assert( inm[0] == 380 ); 
0465         assert( inm[1] == 400 ); 
0466         assert( inm[2] == 420 ); 
0467         assert( inm[3] == 440 ); 
0468         assert( inm[4] == 460 ); 
0469     }
0470     {
0471         const char* wavelength = "0" ; 
0472         std::vector<int> inm ; 
0473         SStr::ISplit(wavelength, inm, ',' ); 
0474         assert( inm.size() == 1 ); 
0475         assert( inm[0] == 0 ); 
0476     }
0477     {
0478         const char* wavelength = "440" ; 
0479         std::vector<int> inm ; 
0480         SStr::ISplit(wavelength, inm, ',' ); 
0481         assert( inm.size() == 1 ); 
0482         assert( inm[0] == 440 ); 
0483     }
0484 
0485 }
0486 
0487 
0488 void test_FormatReal()
0489 {
0490     double value = 1.1 ; 
0491     const char* s = SStr::FormatReal<double>(value, 6, 4, '0'); 
0492 
0493     std::cout 
0494         << " value " << value 
0495         << " s [" << s  << "]" 
0496         << std::endl 
0497         ;
0498 }
0499 
0500 void test_StripPrefix()
0501 {
0502     const char* lines = R"LITERAL(
0503 /dd/Materials/red
0504 /dd/Materials/green
0505 /dd/Materials/blue
0506 _dd_Materials_red
0507 _dd_Materials_green
0508 _dd_Materials_blue
0509 red
0510 green
0511 blue
0512 )LITERAL" ; 
0513 
0514     std::stringstream ss(lines) ;    
0515     std::string line ; 
0516     while (std::getline(ss, line))  
0517     {   
0518         if(line.empty()) continue ;   
0519 
0520         const char* s = line.c_str(); 
0521         const char* sp = SStr::StripPrefix(s, "/dd/Materials/", "_dd_Materials_" );          
0522         const char* sp2 = SStr::MaterialBaseName(s); 
0523 
0524         bool sp_expect = strcmp( sp, sp2 ) == 0  ;
0525         assert(sp_expect); 
0526         if(!sp_expect) std::raise(SIGINT); 
0527 
0528         std::cout 
0529             << std::setw(50) << line 
0530             << " : "
0531             << std::setw(50) << sp
0532             << std::endl
0533             ;
0534     }    
0535 }
0536 
0537 
0538 void test_TrimPointerSuffix()
0539 {
0540     const char* lines = R"LITERAL(
0541 Hello0xdeadbeef
0542 Hello0xnope
0543 Hello0xnope1
0544 Hello0xnope1
0545 Hello0x0123
0546 Hello0x01234
0547 Hello0x012345
0548 Hello0x0123456
0549 Hello0x01234567
0550 Hello0x012345678
0551 Hello0x0123456789
0552 Hello0x0123456789a
0553 Hello0xa
0554 Hello0xab
0555 Hello0xabc
0556 Hello0xabcd
0557 Hello0xabcde
0558 Hello0xabcdef
0559 Hello0xabcdef0
0560 Hello0xabcdef01
0561 Hello0xabcdef012
0562 0xcafecafe
0563 0xdeadbeef
0564 a0xcafecafe
0565 a0xdeadbeef
0566 )LITERAL" ; 
0567 
0568     // the suffix chars must be valid hexdigits
0569 
0570     std::stringstream ss(lines) ;    
0571     std::string line ; 
0572     while (std::getline(ss, line))  
0573     {   
0574         if(line.empty()) continue ;   
0575 
0576         const char* s = line.c_str(); 
0577         const char* sp = SStr::TrimPointerSuffix(s); 
0578         std::cout 
0579             << std::setw(50) << s
0580             << " : "
0581             << std::setw(50) << sp
0582             << std::endl
0583             ;
0584     }    
0585 }
0586 
0587 
0588 void test_ReplaceChars()
0589 {
0590      const char* str0 = "(-0.585,-0.805, 0.098, 0.000) (-0.809, 0.588, 0.000, 0.000) (-0.057,-0.079,-0.995, 0.000) (1022.116,1406.822,17734.953, 1.000)"  ; 
0591      const char* str1 = SStr::ReplaceChars(str0); 
0592 
0593      std::cout 
0594          << " str0 " << str0 << std::endl 
0595          << " str1 " << str1 << std::endl 
0596          ;
0597 }
0598 
0599 void test_ato_()
0600 {
0601     const char* a = "104.25" ; 
0602 
0603     float f = SStr::ato_<float>(a);  
0604     double d = SStr::ato_<double>(a); 
0605     int i = SStr::ato_<int>(a);  
0606     unsigned u = SStr::ato_<unsigned>(a);  
0607 
0608 
0609     LOG(info) 
0610        << " a " << a 
0611        << " f " << std::setw(10) << std::fixed << std::setprecision(4) << f 
0612        << " d " << std::setw(10) << std::fixed << std::setprecision(4) << d
0613        << " i " << std::setw(10) << i 
0614        << " u " << std::setw(10) << u 
0615        ; 
0616 }
0617 
0618 void test_Extract()
0619 {
0620     const char* s = "asjdhajsdhas-100   -200 300 sajdasjdhakjHDKJ +66 21 23 45 1001 -10 akjdshaHD -42 " ; 
0621     LOG(info) << s ; 
0622     std::vector<long> vals ; 
0623     SStr::Extract_(vals, s ); 
0624 
0625     for(unsigned i=0 ; i < vals.size() ; i++ ) std::cout << vals[i] << std::endl;
0626 
0627 }
0628 
0629 void test_Extract_float()
0630 {
0631     const char* s = "asjdhajsdhas-0.1   -.2 +30.5 sajdasjdhakjHDKJ +66 21 23.6 45 1001 -10.2 akjdshaHD -42.5 " ; 
0632     LOG(info) << s ; 
0633     std::vector<float> vals ; 
0634     SStr::Extract_(vals, s ); 
0635 
0636     for(unsigned i=0 ; i < vals.size() ; i++ ) std::cout << vals[i] << std::endl;
0637 }
0638 
0639 void test_Trim(const char* s)
0640 {
0641      std::cout 
0642          << "s                    [" << s << "]" << std::endl 
0643          << "SStr::TrimTrailing(s)[" << SStr::TrimTrailing(s) << "]" << std::endl 
0644          << "SStr::TrimLeading(s) [" << SStr::TrimLeading(s) << "]" << std::endl 
0645          << "SStr::Trim(s)        [" << SStr::Trim(s) << "]" << std::endl 
0646          ;
0647 
0648 }
0649 
0650 
0651 void test_Trim()
0652 {
0653      const char* s0 = "            contents with gaps before whitespace          " ; 
0654      test_Trim(s0);
0655 
0656      const char* s1 = R"LITERAL(     
0657  
0658 red
0659 green
0660 blue cyan magenta
0661 yellow
0662 
0663 
0664 )LITERAL" ;
0665 
0666      test_Trim(s1);
0667 
0668 
0669 }
0670 
0671 void test_Count()
0672 {
0673     assert( SStr::Count("a bcdefg", ' ') == 1 ); 
0674     assert( SStr::Count("a  bcdefg", ' ') == 2 ); 
0675     assert( SStr::Count(" ", ' ') == 1 ); 
0676     assert( SStr::Count("  ", ' ') == 2 ); 
0677     assert( SStr::Count("", ' ') == 0 ); 
0678 }
0679 void test_All()
0680 {
0681     assert( SStr::All("aaaaa", 'a') == true ); 
0682     assert( SStr::All("aabaa", 'a') == false ); 
0683     assert( SStr::All("", 'a') == false ); 
0684     assert( SStr::All(" ", ' ') == true ); 
0685     assert( SStr::All("  ", ' ') == true ); 
0686 }
0687 void test_Blank()
0688 {
0689     assert( SStr::Blank("aaaaa") == false ); 
0690     assert( SStr::Blank("") == true ); 
0691     assert( SStr::Blank(" ") == true ); 
0692     assert( SStr::Blank("  ") == true ); 
0693     assert( SStr::Blank("           ") == true ); 
0694     assert( SStr::Blank("\n") == false ); 
0695 }
0696 
0697 
0698 
0699 
0700 
0701 void test_ExtractLong()
0702 {
0703 
0704      const char* lines = R"LITERAL(     
0705  
0706 red1
0707 green2
0708 blue2 cyan magenta
0709 yellow3
0710 
0711 
0712 )LITERAL" ;
0713 
0714 
0715     std::stringstream ss(lines) ;    
0716     std::string line ; 
0717     while (std::getline(ss, line))  
0718     {   
0719         if(line.empty()) continue ;   
0720 
0721         const char* s = line.c_str(); 
0722         long l = SStr::ExtractLong(s, 0); 
0723 
0724         LOG(info) << std::setw(40) << s << " l: " << l  ; 
0725     }
0726 }
0727 
0728 
0729 void test_HeadFirst_HeadLast()
0730 {
0731     const char* lines = R"LITERAL(
0732 SomeName_suffix
0733 green2WithoutSuffix
0734 MultipleUnderscoreblue2_cyan_magenta
0735 )LITERAL" ;
0736 
0737     std::stringstream ss(lines) ;    
0738     std::string line ; 
0739     while (std::getline(ss, line))  
0740     {   
0741         if(line.empty()) continue ;   
0742 
0743         const char* s = line.c_str(); 
0744         const char* f = SStr::HeadFirst(s, '_'); 
0745         const char* l = SStr::HeadLast(s, '_'); 
0746        
0747         std::cout 
0748             << " s[" << std::setw(40) << ( s ? s : "-" ) << "]" << std::setw(3) << strlen(s) 
0749             << " f[" << std::setw(40) << ( f ? f : "-" ) << "]" << std::setw(3) << strlen(f) 
0750             << " l[" << std::setw(40) << ( l ? l : "-" ) << "]" << std::setw(3) << strlen(l) 
0751             << std::endl 
0752             ;
0753     }
0754 }   
0755 
0756 
0757 void test_Format_Ellipsis()
0758 {
0759     LOG(info) << SStr::Format_("Hello %d World %10.4f", 101, 50.5 ); 
0760     LOG(info) << SStr::Format("Hello %d World %10.4f", 101, 50.5 ); 
0761 
0762     for(int i=0 ; i < 1000 ; i+= 100 ) 
0763     {
0764          std::cout 
0765             << " before " 
0766             << std::setw(7) << SStr::Format("key:%d", i ) 
0767             << " after " 
0768             << std::endl 
0769             ; 
0770     }
0771 
0772     
0773 }
0774 
0775 
0776 void test_StartsWithLetterAZaz()
0777 {
0778     assert( SStr::StartsWithLetterAZaz(nullptr) == false ); 
0779     assert( SStr::StartsWithLetterAZaz("") == false ); 
0780     assert( SStr::StartsWithLetterAZaz(" ") == false ); 
0781     assert( SStr::StartsWithLetterAZaz("0") == false ); 
0782     assert( SStr::StartsWithLetterAZaz("0a") == false ); 
0783     assert( SStr::StartsWithLetterAZaz(" a") == false ); 
0784 
0785     assert( SStr::StartsWithLetterAZaz("a") == true ); 
0786     assert( SStr::StartsWithLetterAZaz("abcd") == true ); 
0787     assert( SStr::StartsWithLetterAZaz("Abcd") == true ); 
0788 }
0789 
0790 
0791 void test_ParseStringIntInt()
0792 {
0793     const char* x0 = "Hello" ; 
0794     int y0 = 10 ; 
0795     int z0 = 1000 ;  
0796     std::stringstream ss ; 
0797     ss << x0 << ":" << y0 << ":" << z0 ; 
0798 
0799     std::string s = ss.str(); 
0800     const char* triplet = s.c_str(); 
0801 
0802     int y1 = 0 ; 
0803     int z1 = 0 ; 
0804     const char* x1 = SStr::ParseStringIntInt(triplet, y1, z1); 
0805 
0806     bool x_expect =  strcmp(x0,x1) == 0 ;
0807     bool y_expect = y0 == y1 ;
0808     bool z_expect = z0 == z1 ;
0809 
0810     assert( x_expect );
0811     assert( y_expect );
0812     assert( z_expect );
0813 
0814     if(!x_expect) std::raise(SIGINT); 
0815     if(!y_expect) std::raise(SIGINT); 
0816     if(!z_expect) std::raise(SIGINT); 
0817 
0818     LOG(info); 
0819 }
0820 
0821 
0822 
0823 // om- ; TEST=SStrTest om-t
0824 
0825 
0826 int main(int argc , char** argv )
0827 {
0828     OPTICKS_LOG(argc, argv);
0829 
0830     /*
0831     test_ToULL();
0832     test_FromULL();
0833     test_Format1();  
0834     test_Contains();  
0835     test_EndsWith();  
0836     test_HasPointerSuffix();  
0837     test_HasPointerSuffix2();  
0838     test_StartsWith();  
0839     test_Replace();  
0840     test_ReplaceEnd();  
0841     test_ArrayToString();  
0842     test_Save();  
0843     test_Split();  
0844     test_Concat_(); 
0845     test_AsInt(); 
0846     test_ExtractInt(); 
0847     test_SimpleMatch_WildMatch(); 
0848     test_ISplit(); 
0849     test_FormatReal(); 
0850     test_StripPrefix(); 
0851     test_TrimPointerSuffix(); 
0852     test_ReplaceChars(); 
0853     test_ato_(); 
0854     test_Save_Load(); 
0855     test_Save_PWD(); 
0856     test_Extract(); 
0857     test_Extract_float(); 
0858     test_Trim(); 
0859     test_Count(); 
0860     test_All(); 
0861     test_Blank(); 
0862     test_ExtractLong(); 
0863     test_HeadFirst_HeadLast(); 
0864     test_FormatInt(); 
0865     test_LoadList(); 
0866     test_Format_Ellipsis(); 
0867     test_StartsWithLetterAZaz(); 
0868     test_FormatInt_2(); 
0869     test_ParseStringIntInt(); 
0870     */
0871     test_FormatIndex(); 
0872 
0873 
0874     return 0  ; 
0875 }
0876 // om-;TEST=SStrTest om-t