00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include <assert.h>
00046 #include <ctype.h>
00047 #include <stdio.h>
00048 #include <stdarg.h>
00049 #include <string.h>
00050
00051 #include "sysc/utils/sc_iostream.h"
00052 #include "sysc/utils/sc_string.h"
00053 #include "sysc/utils/sc_utils_ids.h"
00054
00055 namespace sc_dt {
00056
00057 inline int
00058 sc_roundup( int n, int m )
00059 {
00060 return ((n - 1) / m + 1) * m;
00061 }
00062
00063
00064
00065
00066
00067
00068
00069
00070 const std::string
00071 to_string( sc_numrep numrep )
00072 {
00073 switch( numrep )
00074 {
00075 case SC_DEC:
00076 return std::string( "SC_DEC" );
00077 case SC_BIN:
00078 return std::string( "SC_BIN" );
00079 case SC_BIN_US:
00080 return std::string( "SC_BIN_US" );
00081 case SC_BIN_SM:
00082 return std::string( "SC_BIN_SM" );
00083 case SC_OCT:
00084 return std::string( "SC_OCT" );
00085 case SC_OCT_US:
00086 return std::string( "SC_OCT_US" );
00087 case SC_OCT_SM:
00088 return std::string( "SC_OCT_SM" );
00089 case SC_HEX:
00090 return std::string( "SC_HEX" );
00091 case SC_HEX_US:
00092 return std::string( "SC_HEX_US" );
00093 case SC_HEX_SM:
00094 return std::string( "SC_HEX_SM" );
00095 case SC_CSD:
00096 return std::string( "SC_CSD" );
00097 default:
00098 return std::string( "unknown" );
00099 }
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109 class sc_string_rep
00110 {
00111 friend class sc_string_old;
00112 friend ::std::ostream& operator<<( ::std::ostream&, const sc_string_old& );
00113 friend ::std::istream& operator>>( ::std::istream&, sc_string_old& );
00114 friend sc_string_old operator+( const char*, const sc_string_old& );
00115
00116 sc_string_rep( int size = 16 )
00117 {
00118 ref_count = 1;
00119 alloc = sc_roundup( size, 16 );
00120 str = new char[alloc];
00121 *str = '\0';
00122 }
00123
00124 sc_string_rep( const char* s )
00125 {
00126 ref_count = 1;
00127 if (s) {
00128 alloc = 1 + strlen(s);
00129 str = strcpy( new char[alloc], s );
00130 }
00131 else {
00132 alloc = 16;
00133 str = strcpy( new char[alloc], "" );
00134 }
00135 }
00136
00137 sc_string_rep( const char* s, int n);
00138
00139 ~sc_string_rep()
00140 {
00141 assert( ref_count == 0 );
00142 delete[] str;
00143 }
00144
00145 void resize( int new_size );
00146 void set_string( const char* s );
00147
00148 int ref_count;
00149 int alloc;
00150 char* str;
00151 };
00152
00153
00154
00155
00156 sc_string_rep::sc_string_rep( const char* s, int n)
00157 {
00158 ref_count = 1;
00159 if (s && n>0) {
00160 alloc = 1 + n;
00161 str = strncpy( new char[alloc], s,n );
00162 str[n] = 00;
00163 }
00164 else {
00165 alloc = 16;
00166 str = strcpy( new char[alloc], "" );
00167 }
00168 }
00169
00170 void
00171 sc_string_rep::resize( int new_size )
00172 {
00173 if (new_size <= alloc) return;
00174 alloc = sc_roundup( new_size, 16 );
00175 char* new_str = strcpy( new char[alloc], str );
00176 delete[] str;
00177 str = new_str;
00178 }
00179
00180 void
00181 sc_string_rep::set_string( const char* s )
00182 {
00183 int len = strlen(s);
00184 resize( len + 1 );
00185 strcpy( str, s );
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 sc_string_old::sc_string_old( int size )
00198 {
00199 rep = new sc_string_rep( size );
00200 }
00201
00202 sc_string_old::sc_string_old( const char* s )
00203 {
00204 rep = new sc_string_rep( s );
00205 }
00206
00207 sc_string_old::sc_string_old( const char* s, int n )
00208 {
00209 rep = new sc_string_rep( s, n );
00210 }
00211
00212 sc_string_old::sc_string_old( const sc_string_old& s )
00213 {
00214 rep = s.rep;
00215 rep->ref_count ++;
00216 }
00217
00218 sc_string_old::sc_string_old( sc_string_rep* r )
00219 {
00220 rep = r;
00221 }
00222
00223
00224
00225
00226 sc_string_old::~sc_string_old()
00227 {
00228 if( -- (rep->ref_count) == 0 ) {
00229 delete rep;
00230 }
00231 }
00232
00233
00234 int
00235 sc_string_old::length() const
00236 {
00237 return strlen(rep->str);
00238 }
00239
00240 sc_string_old
00241 sc_string_old::operator+( const char* s ) const
00242 {
00243 int len = length();
00244 sc_string_rep* r = new sc_string_rep( len + strlen(s) + 1 );
00245 strcpy( r->str, rep->str );
00246 strcpy( r->str + len, s );
00247 return sc_string_old(r);
00248 }
00249
00250 sc_string_old sc_string_old::operator+(char c) const
00251 {
00252 int len = length();
00253 sc_string_rep* r = new sc_string_rep( len + 2 );
00254 strcpy( r->str, rep->str );
00255 r->str[len] = c;
00256 r->str[len+1] = 00;
00257 return sc_string_old(r);
00258 }
00259
00260 sc_string_old
00261 operator+( const char* s, const sc_string_old& t )
00262 {
00263 int len = strlen(s);
00264 sc_string_rep* r = new sc_string_rep( len + t.length() + 1 );
00265 strcpy( r->str, s );
00266 strcpy( r->str + len, t );
00267 return sc_string_old(r);
00268 }
00269
00270 sc_string_old
00271 sc_string_old::operator+( const sc_string_old& s ) const
00272 {
00273 int len = length();
00274 sc_string_rep* r = new sc_string_rep( len + s.length() + 1 );
00275 strcpy( r->str, rep->str );
00276 strcpy( r->str + len, s.rep->str );
00277 return sc_string_old(r);
00278 }
00279
00280 sc_string_old&
00281 sc_string_old::operator=( const char* s )
00282 {
00283 if (rep->ref_count > 1) {
00284 --rep->ref_count;
00285 rep = new sc_string_rep(s);
00286 }
00287 else {
00288 rep->set_string(s);
00289 }
00290 return *this;
00291 }
00292
00293 sc_string_old&
00294 sc_string_old::operator=( const sc_string_old& s )
00295 {
00296 if (&s == this)
00297 return *this;
00298 if (--(rep->ref_count) == 0)
00299 delete rep;
00300 rep = s.rep;
00301 rep->ref_count++;
00302 return *this;
00303 }
00304
00305 sc_string_old&
00306 sc_string_old::operator+=( const char* s )
00307 {
00308 int oldlen = length();
00309 int slen = strlen(s);
00310 if (rep->ref_count > 1) {
00311 sc_string_rep* oldrep = rep;
00312 --rep->ref_count;
00313 rep = new sc_string_rep( oldlen + slen + 1 );
00314 strcpy( rep->str, oldrep->str );
00315 strcpy( rep->str + oldlen, s );
00316 }
00317 else {
00318 rep->resize( oldlen + slen + 1 );
00319 strcpy( rep->str + oldlen, s );
00320 }
00321 return *this;
00322 }
00323
00324 sc_string_old& sc_string_old::operator+=(char c)
00325 {
00326 int oldlen = length();
00327 if (rep->ref_count > 1) {
00328 sc_string_rep* oldrep = rep;
00329 --rep->ref_count;
00330 rep = new sc_string_rep( oldlen + 2 );
00331 strcpy( rep->str, oldrep->str );
00332 rep->str[oldlen]=c;
00333 rep->str[oldlen+1]=00;
00334 }
00335 else {
00336 rep->resize( oldlen + 2 );
00337 rep->str[oldlen]=c;
00338 rep->str[oldlen+1]=00;
00339 }
00340 return *this;
00341 }
00342
00343 sc_string_old&
00344 sc_string_old::operator+=( const sc_string_old& s )
00345 {
00346 return this->operator+=( s.rep->str );
00347 }
00348
00349 int
00350 sc_string_old::cmp( const char* s ) const
00351 {
00352 return strcmp( rep->str, s );
00353 }
00354
00355 int
00356 sc_string_old::cmp( const sc_string_old& s ) const
00357 {
00358 return strcmp( rep->str, s.rep->str );
00359 }
00360
00361 const char* sc_string_old::c_str() const
00362 {
00363 return rep->str;
00364 }
00365
00366
00367 sc_string_old sc_string_old::substr(int first,int last) const
00368 {
00369 if(first<0 || last<0 || first>last || first>=length() || last>=length())
00370 return "";
00371 return sc_string_old(rep->str+first, last-first+1);
00372 }
00373
00374
00375 sc_string_old sc_string_old::make_str(long n)
00376 {
00377 char buf[32];
00378 ::std::sprintf(buf,"%ld",n);
00379 return sc_string_old(buf);
00380 }
00381
00382
00383 #define DEFINE_RELOP(op) \
00384 bool sc_string_old::operator op( const char* s ) const \
00385 { \
00386 return strcmp( rep->str, s ) op 0; \
00387 } \
00388 bool sc_string_old::operator op( const sc_string_old& s ) const \
00389 { \
00390 return strcmp( rep->str, s.rep->str ) op 0; \
00391 }
00392
00393 DEFINE_RELOP(==)
00394 DEFINE_RELOP(!=)
00395 DEFINE_RELOP(<)
00396 DEFINE_RELOP(<=)
00397 DEFINE_RELOP(>)
00398 DEFINE_RELOP(>=)
00399
00400 sc_string_old::operator const char*() const
00401 {
00402 return rep->str;
00403 }
00404
00405 char
00406 sc_string_old::operator[]( int i ) const
00407 {
00408 return rep->str[i];
00409 }
00410
00411 char& sc_string_old::operator[]( int i )
00412 {
00413 if (rep->ref_count > 1) {
00414 rep->ref_count--;
00415 rep = new sc_string_rep(rep->str);
00416 }
00417 return rep->str[i];
00418 }
00419
00420 void
00421 sc_string_old::set( int i, char c )
00422 {
00423 if (rep->ref_count > 1) {
00424 rep->ref_count--;
00425 rep = new sc_string_rep(rep->str);
00426 }
00427 rep->str[i] = c;
00428 }
00429
00430 sc_string_old sc_string_old::to_string(const char* format, ...)
00431 {
00432 va_list argptr;
00433 int cnt;
00434 sc_string_old result;
00435 char buffer[1024];
00436 buffer[1023]=000;
00437
00438 va_start(argptr, format);
00439 #if defined(WIN32)
00440
00441 #if defined(_MSC_VER)
00442 cnt = _vsnprintf(buffer, 1024, format, argptr);
00443 #else
00444 cnt = vsnprintf(buffer, 1024, format, argptr);
00445 #endif
00446 if(cnt>1023)
00447 {
00448 int buf_size = 1024;
00449 const int max_size = 65000;
00450 char* buf;
00451 do
00452 {
00453 buf_size*=2;
00454 buf = new char[buf_size];
00455 #if defined(_MSC_VER)
00456 cnt = _vsnprintf(buffer, buf_size, format, argptr);
00457 #else
00458 cnt = vsnprintf(buffer, buf_size, format, argptr);
00459 #endif
00460 if(buf_size<max_size && cnt>=buf_size)
00461 delete[] buf;
00462 }
00463 while( buf_size<max_size && cnt>=buf_size);
00464 if(cnt>=buf_size)
00465 {
00466
00467 SC_REPORT_WARNING( sc_core::SC_ID_STRING_TOO_LONG_, "truncated" );
00468 buf[buf_size-1] = 000;
00469 }
00470 result = buf;
00471 delete[] buf;
00472 }
00473 else
00474 result = buffer;
00475 #else
00476 try {
00477
00478
00479 cnt = vsprintf(buffer, format, argptr);
00480 }
00481 catch(...)
00482 {
00483 SC_REPORT_WARNING( sc_core::SC_ID_STRING_TOO_LONG_,
00484 "program may become unstable" );
00485 }
00486 buffer[1023]=000;
00487 result = buffer;
00488 #endif
00489 va_end(argptr);
00490
00491 return result;
00492 }
00493
00494 void
00495 sc_string_old::print( ::std::ostream& os ) const
00496 {
00497 os << rep->str;
00498 }
00499
00500 void sc_string_old::test(int position)const
00501 {
00502 if(position<0 || position>=length())
00503 SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, "sc_string_old::test" );
00504 }
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515 unsigned
00516 sc_string_old::fmt_length()const
00517 {
00518 unsigned result=0;
00519 if((*this)[0]!='%')
00520 return 0;
00521 else
00522 result++;
00523 if(is_delimiter("-+0 #",result))
00524 result++;
00525 while(is_delimiter("0123456789*",result))
00526 result++;
00527 if(rep->str[result]=='.')
00528 {
00529 result++;
00530 unsigned old_result = result;
00531 while(is_delimiter("0123456789*",result)) result++;
00532 if(old_result == result)
00533 return 0;
00534 }
00535 if(is_delimiter("hlL",result)) result++;
00536 if(is_delimiter("cCdiouxXeEfgGnpsS",result))
00537 result++;
00538 else
00539 return 0;
00540 return result;
00541 }
00542
00543 sc_string_old&
00544 sc_string_old::fmt(const sc_string_old& s)
00545 {
00546 return fmt(s.c_str());
00547 }
00548
00549 int
00550 sc_string_old::pos( const sc_string_old& sub_string ) const
00551 {
00552 int sub_len = sub_string.length();
00553 if( sub_len == 0 ) {
00554 return 0;
00555 }
00556 int ind = 0;
00557 int len = length();
00558 bool found = false;
00559 while( ind < len && ! found )
00560 {
00561 found = ( sub_string == substr( ind, ind + sub_len - 1 ) );
00562 ++ ind;
00563 }
00564 if( found ) {
00565 return -- ind;
00566 } else {
00567 return -1;
00568 }
00569 }
00570
00571 sc_string_old&
00572 sc_string_old::remove(unsigned index, unsigned length)
00573 {
00574 test((int)index);
00575 if(length!=0)
00576 (*this) = substr(0,index-1) + substr(index+length,this->length()-1);
00577 return *this;
00578 }
00579
00580 sc_string_old&
00581 sc_string_old::insert(const sc_string_old& sub_string, unsigned index)
00582 {
00583 if(index>(unsigned)length())
00584 SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, "sc_string_old::insert" );
00585 return (*this) = substr(0,index-1)+sub_string+substr(index,length()-1);
00586 }
00587
00588 bool
00589 sc_string_old::is_delimiter(const sc_string_old& str, unsigned index)const
00590 {
00591 test((int)index);
00592 return str.contains(rep->str[index]);
00593 }
00594
00595 bool
00596 sc_string_old::contains(char c)const
00597 {
00598 int len = length();
00599 int i=0;
00600 bool found = false;
00601 while(!found && i<len)
00602 found = rep->str[i++]==c;
00603 return found;
00604 }
00605
00606 sc_string_old
00607 sc_string_old::uppercase()const
00608 {
00609 int len = length();
00610 sc_string_old temp(*this);
00611 for(int i=0; i<len; i++)
00612 {
00613 char c = temp.rep->str[i];
00614 if(c>='a' && c<='z')
00615 temp.rep->str[i] = static_cast<char>( c-32 );
00616 }
00617 return temp;
00618 }
00619
00620 sc_string_old
00621 sc_string_old::lowercase()const
00622 {
00623 int len = length();
00624 sc_string_old temp(*this);
00625 for(int i=0; i<len; i++)
00626 {
00627 char c = temp.rep->str[i];
00628 if(c>='A' && c<='Z')
00629 temp.rep->str[i] = static_cast<char>( c+32 );
00630 }
00631 return temp;
00632 }
00633
00634
00635
00636
00637 ::std::istream&
00638 operator >> ( ::std::istream& is, sc_string_old& s )
00639 {
00640 if( s.rep->ref_count > 1 ) {
00641 -- s.rep->ref_count;
00642 s.rep = new sc_string_rep;
00643 }
00644
00645 int i = 0;
00646 char* p = s.rep->str;
00647 char c;
00648
00649
00650 while( is.get( c ) && isspace( c ) )
00651 ;
00652
00653 for( ; is.good() && ! isspace( c ); is.get( c ) ) {
00654 if( i > s.rep->alloc - 2 ) {
00655 s.rep->str[i] = '\0';
00656 s.rep->resize( (int) (s.rep->alloc * 1.5) );
00657 p = s.rep->str + i;
00658 }
00659 *p ++ = c;
00660 i ++;
00661 }
00662 *p = '\0';
00663
00664 return is;
00665 }
00666 }