mstring.temp.h

Go to the documentation of this file.
00001 
00013 #ifndef tchar
00014 #error These templates require 'tchar' to be defined so they know what sort of \
00015 characters to make.  'tchar' may be 'wchar_t' or 'char'.
00016 #endif
00017 
00018 #ifndef handler
00019 #error These templates require 'handler' to be defined so they know what to do \
00020 when the end of the buffer is reached. 'handler' may be 'grow' or 'fixed'
00021 #endif
00022 
00024 #define ctl_mstring_growcode(tchar,handler, self, addLen)   ppConcat3(ctl_mstring_,handler,_growcode)(tchar, self, addLen )
00025 
00026 #define ctl_mstring_check(tchar,handler, self, addLen)      ppConcat3(ctl_mstring_,handler,_check)(tchar, self, addLen )
00027 
00028 #define ctl_mstring_checkabort(tchar,handler, self, addLen) ppConcat3(ctl_mstring_,handler,_checkabort)(tchar, self, addLen )
00029 
00030 /* Handler to grow to meet needs */
00032 #define ctl_mstring_grow_growcode(tchar, self, addLen ) \
00033 { \
00034     tchar* begin; \
00035     size_t need; \
00036     assertobjptr(self);\
00037     begin = (self)->begin; \
00038     need = ((self)->end+(addLen)+1-begin); \
00039     if( need > (size_t)((self)->endBuff - (self)->begin) ) \
00040     {\
00041         need += ctl_mstring_delta;\
00042         if( (self)->begin == ctl_mstring_(tchar,handler,0) )\
00043             (self)->begin = NULL;\
00044         ctl_realloc((self)->begin,ctl_chsize(tchar,need)); \
00045         (self)->end = (self)->begin + ((self)->end - begin);\
00046         *(self)->end = 0;\
00047         (self)->endBuff = (self)->begin + need-1;\
00048     }\
00049 }
00050 #define ctl_mstring_grow_check(tchar, self, addLen )        ctl_mstring_(tchar,grow, grow )( self, addLen )
00051 #define ctl_mstring_grow_checkabort(tchar, self, addLen )   ctl_mstring_(tchar,grow, grow )( self, addLen )
00052 #define ctl_mstring_delta   64
00053 
00055 #define ctl_mstring_fixed_growcode(tchar, self, addLen ) {}
00056 
00058 #define ctl_mstring_fixed_check(tchar, self, addLen )\
00059 { \
00060     assertobjptr(self);\
00061     if( (size_t)(addLen) > (size_t)((self)->endBuff-(self)->end) ) \
00062         (addLen) = (size_t)((self)->endBuff-(self)->end); \
00063     if( !(addLen) ) \
00064     {\
00065         *(self)->endBuff = 0;\
00066         return; \
00067     }\
00068 }
00069 
00071 #define ctl_mstring_fixed_checkabort(tchar, self, addLen )\
00072 { \
00073     assertobjptr(self);\
00074     if( (size_t)(addLen) > (size_t)((self)->endBuff-(self)->end) ) \
00075     {\
00076         *(self)->endBuff = 0;\
00077         return; \
00078     }\
00079 }
00080 
00081 
00087 ctl_mstring_xgrow(tchar,handler, const tchar ctl_mstring_(tchar,handler,0)[1] = szconst(tchar,""); ) /* Needed for empty/growable string */
00088 
00096 void ctl_mstring_(tchar,handler, grow )( ctl_mstring(tchar,handler)* self, size_t addLen )  \
00097     ctl_mstring_growcode(tchar,handler, self, addLen)
00098 
00107 void ctl_mstring_(tchar,handler, fill )( ctl_mstring(tchar,handler)* self, tchar fillVal, size_t count )
00108 {
00109     ctl_mstring_check(tchar,handler, self, count );
00110     {
00111         tchar* p = self->end;
00112         const tchar* e = p + count;
00113         while( p < e )
00114             *p++ = fillVal;
00115         self->end = p;
00116         *p = 0;
00117     }
00118 }
00119 
00128 void ctl_mstring_(tchar,handler, filltab )( ctl_mstring(tchar,handler)* self, tchar fillVal, size_t tabPos )
00129 {
00130     size_t index = self->end - self->begin;
00131     if( index < tabPos )
00132         ctl_mstring_(tchar,handler, fill )( self, fillVal, tabPos - index );
00133 }
00134 
00142 void ctl_mstring_(tchar,handler, putint32 )( ctl_mstring(tchar,handler)* self, int32 value )
00143 {
00144     size_t need = int32_NumPlaces( value );
00145     size_t count = need;
00146     ctl_mstring_check(tchar,handler, self, count );
00147     ctl_mstring_xfixed(tchar,handler, if( count < need ) return );
00148     {
00149         tchar* p = self->end;
00150         if( value < 0 )
00151             *p++ = chconst(tchar,'-');
00152         p = self->end += need;
00153         *p-- = 0;
00154         do
00155         {
00156             int32 digit = abs_mod(int32,value,10);
00157             value = value/10;
00158             *p-- = (tchar)(chconst(tchar,'0')+digit);
00159         }
00160         while( value );
00161     }
00162 }
00163 
00171 void ctl_mstring_(tchar,handler, putuint32 )( ctl_mstring(tchar,handler)* self, uint32 value )
00172 {
00173     size_t need = uint32_NumPlaces( value );
00174     size_t count = need;
00175     ctl_mstring_check(tchar,handler, self, count );
00176     ctl_mstring_xfixed(tchar,handler, if( count < need ) return );
00177     {
00178         tchar* p = self->end;
00179         p = self->end += need;
00180         *p-- = 0;
00181         do
00182         {
00183             uint32 digit = abs_mod(uint32,value,10);
00184             value = value/10;
00185             *p-- = (tchar)(chconst(tchar,'0')+digit);
00186         }
00187         while( value );
00188     }
00189 }
00190 
00198 void ctl_mstring_(tchar,handler, putint64 )( ctl_mstring(tchar,handler)* self, int64 value )
00199 {
00200     size_t need = int64_NumPlaces( value );
00201     size_t count = need;
00202     ctl_mstring_check(tchar,handler, self, count );
00203     ctl_mstring_xfixed(tchar,handler, if( count < need ) return );
00204     {
00205         tchar* p = self->end;
00206         if( value < 0 )
00207             *p++ = chconst(tchar,'-');
00208         p = self->end += need;
00209         *p-- = 0;
00210         do
00211         {
00212             int64 digit = abs_mod(int64,value,10);
00213             value = value/10;
00214             *p-- = (tchar)(chconst(tchar,'0')+digit);
00215         }
00216         while( value );
00217     }
00218 }
00219 
00227 void ctl_mstring_(tchar,handler, putuint64 )( ctl_mstring(tchar,handler)* self, uint64 value )
00228 {
00229     size_t need = uint64_NumPlaces( value );
00230     size_t count = need;
00231     ctl_mstring_check(tchar,handler, self, count );
00232     ctl_mstring_xfixed(tchar,handler, if( count < need ) return );
00233     {
00234         tchar* p = self->end;
00235         if( value < 0 )
00236             *p++ = chconst(tchar,'-');
00237         p = self->end += need;
00238         *p-- = 0;
00239         do
00240         {
00241             uint64 digit = abs_mod(uint64,value,10);
00242             value = value/10;
00243             *p-- = (tchar)(chconst(tchar,'0')+digit);
00244         }
00245         while( value );
00246     }
00247 }
00248 
00256 void ctl_mstring_(tchar,handler, putfloat64 )( ctl_mstring(tchar,handler)* self, float64 value )
00257 {
00258     /* There is no wide snprintf, so make do. */
00259     char buff[32];
00260     /* It's SERIOUSLY screwed that there aren't wide-character sprintf things! */
00261     csnprintf(char)(buff,32, szconst(char,"%.6f"), (double)(value) ); 
00262     ppCtypeSelect(tchar,ctl_mstring_(tchar,handler, strncat )( self, buff, countof(buff) );,{ char* pbuff = buff; while( *pbuff ) { ctl_mstring_(tchar,handler, fill )((self), (tchar)*pbuff, 1 ); pbuff++; } })
00263 }
00264 
00272 void ctl_mstring_(tchar,handler, putxuint32 )( ctl_mstring(tchar,handler)* self, uint32 value, size_t places )
00273 {
00274     size_t count = places;
00275     ctl_mstring_check(tchar,handler, self, count );
00276     ctl_mstring_xfixed(tchar,handler, if( count < places ) return );
00277     {
00278         tchar* p = self->end += places;
00279         *p-- = 0;
00280         while( p >= self->end )
00281         {
00282             tchar ch = (tchar)(chconst(tchar,'0') + (value & 0xf));
00283             if( ch > chconst(tchar,'9') )
00284                 ch += (chconst(tchar,'A')-(chconst(tchar,'9')+1));
00285             *p-- = ch;
00286             value>>=4;
00287         }
00288     }
00289 }
00290 
00298 void ctl_mstring_(tchar,handler, putxuint64 )( ctl_mstring(tchar,handler)* self, uint64 value, size_t places )
00299 {
00300     size_t count = places;
00301     ctl_mstring_check(tchar,handler, self, count );
00302     ctl_mstring_xfixed(tchar,handler, if( count < places ) return );
00303     {
00304         tchar* p = self->end += places;
00305         *p-- = 0;
00306         while( p >= self->end )
00307         {
00308             tchar ch = (tchar)(chconst(tchar,'0') + (value & 0xf));
00309             if( ch > chconst(tchar,'9') )
00310                 ch += (chconst(tchar,'A')-(chconst(tchar,'9')+1));
00311             *p-- = ch;
00312             value>>=4;
00313         }
00314     }
00315 }
00316 
00326 void ctl_mstring_(tchar,handler, putenum )( ctl_mstring(tchar,handler)* self, int value, const tchar* const* const szzList, int max, const tchar* szUndefined )
00327 {
00328     if( value >= max )
00329         ctl_mstring_(tchar,handler, strncat )( self, szUndefined, ~0u );
00330     else
00331         ctl_mstring_(tchar,handler, strncat )( self, szzList[value], ~0u );
00332 }
00333 
00342 void ctl_mstring_(tchar,handler, strncat )( ctl_mstring(tchar,handler)* self, const tchar* sz, size_t maxLen )
00343 {
00344     size_t count = cstrnlen(tchar)(sz,maxLen);
00345     ctl_mstring_check(tchar,handler, self, count );
00346     cmemcpy(tchar, self->end, sz, count );
00347     self->end += count;
00348     *self->end = 0;
00349 }
00350 
00360 void ctl_mstring_(tchar,handler, strncpy )( ctl_mstring(tchar,handler)* self, const tchar* sz, size_t maxLen )
00361 {
00362     size_t count;
00363     assertconst(sz,sizeof(tchar));
00364     count = cstrnlen(tchar)(sz,maxLen);
00365     ctl_mstring_check(tchar,handler, self, count );
00366     cmemcpy(tchar, self->begin, sz, count );
00367     self->end = self->begin + count;
00368     *self->end = 0;
00369 }
00370 
00381 void ctl_mstring_(tchar,handler, strninsert )( ctl_mstring(tchar,handler)* self, size_t position, const tchar* sz, size_t maxLen )
00382 {
00383     size_t count;
00384     assertconst(sz,sizeof(tchar));
00385     count = cstrnlen(tchar)(sz,maxLen);
00386     ctl_mstring_check(tchar,handler, self, count );
00387     {
00388         size_t countAfter = (self->end-self->begin) - position;
00389         if( countAfter < 0 )
00390             ctl_mstring_(tchar,handler, fill )( self, szconst(tchar,' '), count );
00391         else if( countAfter > 0 )
00392             cmemmove(tchar, self->begin + position + count, self->begin + position, countAfter );
00393         cmemcpy(tchar, self->begin + position, sz, count );
00394         self->end += count;
00395         *self->end = 0;
00396     }
00397 }
00398 
00408 void ctl_mstring_(tchar,handler, vsprintf )( ctl_mstring(tchar,handler)* self, const tchar* fmt, va_list args )
00409 {
00410     int count;
00411     int result;
00412     assertconst(fmt,sizeof(tchar));
00413     assertobjptr(self);
00414     count = (int)(self->endBuff - self->end);
00415     result = cvsnprintf(tchar)( self->end, count, fmt, args );
00416     if( 0 > result )
00417     {
00418         tchar* tmp = NULL;
00419         size_t len = 128;
00420         do {
00421             ctl_realloc(tmp,len);
00422             result = cvsnprintf(tchar)(tmp, len, fmt, args );
00423             len <<= 1;
00424         } while(result < 0);
00425         ctl_free(tmp);
00426     }
00427     if( result < count )
00428     {
00429         self->end += result;
00430         *self->end = 0;
00431         return;
00432     }
00433     ctl_mstring_checkabort(tchar,handler, self, result );
00434     ctl_mstring_xgrow(tchar,handler, self->end += cvsnprintf(tchar)(self->end, self->endBuff - self->end, fmt, args ); *self->end = 0; )
00435 }
00444 void ctl_mstring_(tchar,handler, sprintf )( ctl_mstring(tchar,handler)* self, const tchar* fmt, ... )
00445 {
00446     va_list args;
00447     va_start(args, fmt);
00448     ctl_mstring_(tchar,handler, vsprintf )( self, fmt, args );
00449 }
00450 
00458 void ctl_mstring_(tchar,handler, makeClabel )( ctl_mstring(tchar,handler)* self )
00459 {
00460     tchar* e, *p;
00461     assertobjptr(self);
00462     e = self->end;
00463     for( p = self->begin; p < e; ++p )
00464         if( !cisalpha(tchar)(*p) && !cisdigit(tchar)(*p) )
00465             *p = '_';
00466 }
00467 
00476 void ctl_mstring_(tchar,handler, truncate )( ctl_mstring(tchar,handler)* self, size_t newsize )
00477 {
00478     assertobjptr(self);
00479     if( newsize <= (size_t)(self->end - self->begin) )
00480     {
00481         self->end = self->begin + newsize;
00482         *self->end = 0;
00483     }
00484 }
00485 
00495 int ctl_mstring_(tchar,handler, rcompare )( const ctl_mstring(tchar,handler)* p1, const ctl_mstring(tchar,handler)* p2 )
00496 {
00497     assertobjconst(p1);
00498     assertobjconst(p2);
00499     return ctl_mstring_(tchar,handler, compare )( p1, p1 );
00500 }
00501 
00511 int ctl_mstring_(tchar,handler, compare )( const ctl_mstring(tchar,handler)* p1, const ctl_mstring(tchar,handler)* p2 )
00512 {
00513     assertobjconst(p1);
00514     assertobjconst(p2);
00515     {
00516         int diff;
00517         size_t lenp1 = (p1->end-p1->begin);
00518         size_t lenp2 = (p2->end-p2->begin);
00519         size_t count = min(lenp1,lenp2);
00520         const tchar* pp1 = p1->begin;
00521         const tchar* pp2 = p2->begin;
00522         while( count-- )
00523         {
00524             diff = *pp1++ - *pp2++;
00525             if( diff )
00526                 return diff;
00527         }
00528         if( lenp1 > lenp2 )
00529             return 1;
00530         if( lenp1 < lenp2 )
00531             return -1;
00532     }
00533     return 0;
00534 }
00535 
00546 int ctl_mstring_(tchar,handler, strncmp )( const ctl_mstring(tchar,handler)* p1, const tchar* p2, size_t p2len )
00547 {
00548     assertobjconst(p1);
00549     assertconst(p2,sizeof(tchar));
00550     {
00551         const tchar* pp1 = p1->begin;
00552         const tchar* pp2 = p2;
00553         size_t lenp1 = (p1->end-p1->begin);
00554         size_t lenp2 = cstrnlen(tchar)(p2,p2len);
00555         size_t count = min(lenp2,lenp1);
00556         while( count-- )
00557         {
00558             int diff = *pp1++ - *pp2++;
00559             if( diff )
00560                 return diff;
00561         }
00562         if( lenp1 > lenp2 )
00563             return 1;
00564         if( lenp1 < lenp2 )
00565             return -1;
00566     }
00567     return 0;
00568 }
00569 
00580 int ctl_mstring_(tchar,handler, strnicmp )( const ctl_mstring(tchar,handler)* p1, const tchar* p2, size_t p2len )
00581 {
00582     assertobjconst(p1);
00583     assertconst(p2,sizeof(tchar));
00584     {
00585         const tchar* pp1 = p1->begin;
00586         const tchar* pp2 = p2;
00587         size_t lenp1 = (p1->end-p1->begin);
00588         size_t lenp2 = cstrnlen(tchar)(p2,p2len);
00589         size_t count = min(lenp2,lenp1);
00590         while( count-- )
00591         {
00592             int diff = toupper(*pp1++) - toupper(*pp2++);
00593             if( diff )
00594                 return diff;
00595         }
00596         if( lenp1 > lenp2 )
00597             return 1;
00598         if( lenp1 < lenp2 )
00599             return -1;
00600     }
00601     return 0;
00602 }

Generated on Fri Jan 2 15:28:34 2009 for Squat by  doxygen 1.5.6