Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/cstr is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 #ifndef tools_cstr
0005 #define tools_cstr
0006 
0007 #include <cstring> // strcpy
0008 #include <cstdlib> // malloc,free
0009 
0010 #ifdef TOOLS_MEM
0011 #include "mem"
0012 //#define TOOLS_CSTR_DEBUG_MEM
0013 #ifdef TOOLS_CSTR_DEBUG_MEM
0014 #include <cstdio>
0015 #endif
0016 #endif
0017 
0018 namespace tools {
0019 
0020 // NOTE : have str_ to avoid clashes with various strxxx cpp macro
0021 //        that may come from C or system headers.
0022 
0023 #ifdef TOOLS_MEM
0024 inline const std::string& s_cstr() {
0025   static const std::string s_v("tools::cstr");
0026   return s_v;
0027 }
0028 #endif
0029 
0030 inline char* str_dup(const char* a_cstr
0031 #ifdef TOOLS_MEM
0032                      ,bool a_inc = true
0033 #endif
0034                      ) {
0035 #ifdef TOOLS_MEM
0036   if(a_inc) {
0037 #ifdef TOOLS_CSTR_DEBUG_MEM
0038     ::printf("debug : str_dup \"%s\"\n",a_cstr);
0039 #endif
0040     mem::increment(s_cstr().c_str());
0041   }
0042 #endif
0043   return ::strcpy((char*)::malloc(::strlen(a_cstr)+1),a_cstr);
0044 }
0045 
0046 inline char* str_from_buffer(const char* a_buffer,size_t a_len
0047 #ifdef TOOLS_MEM
0048                      ,bool a_inc = true
0049 #endif
0050                      ) {
0051 #ifdef TOOLS_MEM
0052   if(a_inc) {
0053 #ifdef TOOLS_CSTR_DEBUG_MEM
0054     ::printf("debug : str_from_buffer.\n");
0055 #endif
0056     mem::increment(s_cstr().c_str());
0057   }
0058 #endif
0059   char* _s = (char*)::malloc(a_len+1);
0060   if(_s==NULL) return NULL;
0061   _s = ::strncpy(_s,a_buffer,a_len);
0062   _s[a_len] = 0;
0063   return _s;
0064 }
0065 
0066 inline void str_del(char*& a_cstr) {
0067   if(a_cstr==NULL) return;
0068 #ifdef TOOLS_MEM
0069 #ifdef TOOLS_CSTR_DEBUG_MEM
0070   ::printf("debug : str_del \"%s\"\n",a_cstr);
0071 #endif
0072   mem::decrement(s_cstr().c_str());
0073 #endif
0074   ::free(a_cstr);
0075   a_cstr = NULL;
0076 }
0077 
0078 inline char* str_new(size_t a_l = 0,char a_char = ' ') {
0079   char* _s = (char*)::malloc((a_l+1)*sizeof(char));
0080   if(_s==NULL) return NULL;
0081 #ifdef TOOLS_MEM
0082 #ifdef TOOLS_CSTR_DEBUG_MEM
0083   ::printf("debug : str_new : len %lu\n",a_l);
0084 #endif
0085   mem::increment(s_cstr().c_str());
0086 #endif
0087   char* pos = _s;
0088   for(size_t c=0;c<a_l;c++,pos++) *pos = a_char;
0089   *(_s+a_l) = 0;
0090   return _s;
0091 }
0092 
0093 inline bool str_cat(char*& a_1,const char a_c) {
0094   size_t l1 = ::strlen(a_1);
0095   char* _s = (char*)::malloc(l1+1+1);
0096   if(!_s) return false;
0097 #ifdef TOOLS_MEM
0098 #ifdef TOOLS_CSTR_DEBUG_MEM
0099   ::printf("debug : str_cat \"%s\", char %d\n",a_1,a_c);
0100 #endif
0101   mem::increment(s_cstr().c_str());
0102 #endif
0103   ::memcpy(_s,a_1,l1);
0104   ::memcpy(_s+l1,&a_c,1);
0105   *(_s+l1+1) = 0;
0106   ::free(a_1);
0107 #ifdef TOOLS_MEM
0108 #ifdef TOOLS_CSTR_DEBUG_MEM
0109   ::printf("debug : str_cat : dec\n");
0110 #endif
0111   mem::decrement(s_cstr().c_str());
0112 #endif
0113   a_1 = _s;
0114   return true;
0115 }
0116 
0117 inline bool str_cat(char*& a_1,const char* a_2) {
0118   size_t l1 = ::strlen(a_1);
0119   size_t l2 = ::strlen(a_2);
0120   char* _s = (char*)::malloc(l1+l2+1);
0121   if(!_s) return false;
0122 #ifdef TOOLS_MEM
0123 #ifdef TOOLS_CSTR_DEBUG_MEM
0124   ::printf("debug : str_cat \"%s\" \"%s\"\n",a_1,a_2);
0125 #endif
0126   mem::increment(s_cstr().c_str());
0127 #endif
0128   ::memcpy(_s,a_1,l1);
0129   ::memcpy(_s+l1,a_2,l2);
0130   *(_s+l1+l2) = 0;
0131   ::free(a_1);
0132 #ifdef TOOLS_MEM
0133 #ifdef TOOLS_CSTR_DEBUG_MEM
0134   ::printf("debug : str_cat : dec\n");
0135 #endif
0136   mem::decrement(s_cstr().c_str());
0137 #endif
0138   a_1 = _s;
0139   return true;
0140 }
0141 
0142 inline void str_rev(char* a_s) {
0143   size_t l = ::strlen(a_s);
0144   size_t hl = l/2;
0145   char* beg = a_s;
0146   char* end = a_s+l-1;
0147   for(size_t i=0;i<hl;i++) {
0148     char c = *end;
0149     *end = *beg;
0150     *beg = c;
0151     beg++;end--;
0152   }
0153 }
0154 
0155 inline char* str_sub(const char* a_s,
0156                      unsigned int a_pos,
0157                      unsigned int a_sz = 0) { //0 = take up end.
0158   size_t l = ::strlen(a_s);
0159   if(a_pos>=l) return 0; //throw std::out_of_range
0160   size_t ls;
0161   if(a_sz) {
0162     ls = (a_sz<(l-a_pos)?a_sz:(l-a_pos)); //min(a_sz,l-a_pos)
0163   } else {
0164     ls = l-a_pos;
0165   }
0166   char* _s = (char*)::malloc(ls+1);
0167   if(!_s) return 0;
0168 #ifdef TOOLS_MEM
0169 #ifdef TOOLS_CSTR_DEBUG_MEM
0170   ::printf("debug : str_sub \"%s\"\n",a_s);
0171 #endif
0172   mem::increment(s_cstr().c_str());
0173 #endif
0174   //abcdefgh  l=8
0175   //0123456789
0176   ::memcpy(_s,a_s+a_pos,ls);
0177   *(_s+ls) = 0;
0178   return _s;
0179 }
0180 
0181 inline char* str_rep(const char* a_s,unsigned int a_pos,unsigned int a_sz,const char* a_new) {
0182   //not tested yet.
0183   size_t las = ::strlen(a_s);
0184   if(a_pos>=las) return 0; //throw std::out_of_range
0185   if(a_pos+a_sz>las) return 0;
0186   size_t lan = ::strlen(a_new);
0187   unsigned int num = a_sz<lan?a_sz:(unsigned int)lan;
0188   //abcdefghij : l = 10
0189   //0123456789
0190   //   p
0191   size_t le = las-(a_pos+a_sz);
0192   size_t ls = a_pos+num+le;
0193   char* _s = (char*)::malloc(ls+1);
0194   if(!_s) return 0;
0195 #ifdef TOOLS_MEM
0196 #ifdef TOOLS_CSTR_DEBUG_MEM
0197   ::printf("debug : str_rep \"%s\"\n",a_s);
0198 #endif
0199   mem::increment(s_cstr().c_str());
0200 #endif
0201   ::memcpy(_s,a_s,a_pos);
0202   ::memcpy(_s+a_pos,a_new,num);
0203   if(le) ::memcpy(_s+a_pos+num,a_s+a_pos+a_sz,le);
0204   *(_s+ls) = 0;
0205   return _s;
0206 }
0207 
0208 inline void str_skip(char*& a_cstr,char a_c) {
0209   while(true) {
0210     if(*a_cstr!=a_c) break;
0211     a_cstr++;
0212   }
0213 }
0214 
0215 }
0216 
0217 #include <clocale>
0218 
0219 namespace tools {
0220 
0221 inline char* beg_LC_NUMERIC() {
0222   char* _sl = ::setlocale(LC_NUMERIC,0);
0223   char* old = _sl?str_dup(_sl):0;
0224   ::setlocale(LC_NUMERIC,"C");
0225   return old;
0226 }
0227 inline void end_LC_NUMERIC(char*& a_s) {
0228   if(a_s) {
0229     ::setlocale(LC_NUMERIC,a_s);
0230     str_del(a_s);
0231   }
0232 }
0233 
0234 inline bool str_2d(const char* a_s,double& a_v) {
0235   char* olcn = beg_LC_NUMERIC();
0236 
0237   char* end;
0238   a_v = ::strtod(a_s,&end);
0239   if(end==a_s) {
0240     a_v = 0;
0241     end_LC_NUMERIC(olcn);
0242     return false;
0243   }
0244 
0245   end_LC_NUMERIC(olcn);
0246   return true;
0247 }
0248 
0249 /*
0250 inline bool str_2d(const char* a_s,double& a_v) {
0251   char* _sl = ::setlocale(LC_NUMERIC,0);
0252   char* old = _sl?str_dup(_sl):0;
0253   ::setlocale(LC_NUMERIC,"C");
0254 
0255   char* end;
0256   a_v = ::strtod(a_s,&end);
0257   bool status = true;
0258   if(end==a_s) {
0259     status = false;
0260     a_v = 0;
0261   }
0262 
0263   if(old) {
0264     ::setlocale(LC_NUMERIC,old);
0265     str_del(old);
0266   }
0267 
0268   return status;
0269 }
0270 */
0271 
0272 inline size_t str_lcpy(char *dst, const char *src, size_t siz) {
0273   // Copy src to string dst of size siz.  At most siz-1 characters
0274   // will be copied.  Always NUL terminates (unless siz == 0).
0275   // Returns strlen(src); if retval >= siz, truncation occurred.
0276 
0277   // code taken from CERN-ROOT/core/clib to compile exlib/tests/h2root.cpp.
0278   // strlcpy, strlcat are in string.h on BSD based systems.
0279 
0280   // Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>.
0281 
0282   /*register*/ char* d = dst;
0283   /*register*/ const char* _s = src;
0284   /*register*/ size_t n = siz;
0285 
0286   // Copy as many bytes as will fit :
0287   if (n != 0 && --n != 0) {
0288     do {
0289       if ((*d++ = *_s++) == 0) break;
0290     } while (--n != 0);
0291   }
0292 
0293   // Not enough room in dst, add NUL and traverse rest of src :
0294   if (n == 0) {
0295     if (siz != 0) *d = '\0';  // NUL-terminate dst.
0296     while (*_s++);
0297   }
0298 
0299   return(_s - src - 1); // count does not include NUL.
0300 }
0301 
0302 inline size_t str_lcat(char *dst, const char *src, size_t siz) {
0303   // Appends src to string dst of size siz (unlike strncat, siz is the
0304   // full size of dst, not space left).  At most siz-1 characters
0305   // will be copied.  Always NUL terminates (unless siz <= strlen(dst)).
0306   // Returns strlen(src) + MIN(siz, strlen(initial dst)).
0307   // If retval >= siz, truncation occurred.
0308 
0309   // code taken from CERN-ROOT/core/clib to compile exlib/tests/h2root.cpp.
0310   // strlcpy, strlcat are in string.h on BSD based systems.
0311 
0312   // Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>.
0313 
0314   /*register*/ char* d = dst;
0315   /*register*/ const char* _s = src;
0316   /*register*/ size_t n = siz;
0317   size_t dlen;
0318 
0319   // Find the end of dst and adjust bytes left but don't go past end :
0320   while (n-- != 0 && *d != '\0') d++;
0321   dlen = d - dst;
0322   n = siz - dlen;
0323 
0324   if (n == 0) return(dlen + strlen(_s));
0325 
0326   while (*_s != '\0') {
0327     if (n != 1) {
0328       *d++ = *_s;
0329       n--;
0330     }
0331     _s++;
0332   }
0333   *d = '\0';
0334 
0335   return(dlen + (_s - src)); // count does not include NUL.
0336 }
0337 
0338 template <class VECTOR>
0339 inline bool str_2ds(char* a_s,const char* a_sep,VECTOR& a_v) {
0340   a_v.clear();
0341   const char* tok;
0342   double d;
0343   for (tok = ::strtok(a_s,a_sep);tok && *tok;tok = ::strtok(NULL,a_sep)) {
0344     if(!str_2d(tok,d)) {a_v.clear();return false;}
0345     a_v.push_back(d);
0346   }
0347   return true;
0348 }
0349 
0350 }
0351 
0352 #endif