Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 2 // See the file tools.license for terms. 3 3 4 #ifndef tools_cstr 4 #ifndef tools_cstr 5 #define tools_cstr 5 #define tools_cstr 6 6 7 #include <cstring> // strcpy 7 #include <cstring> // strcpy 8 #include <cstdlib> // malloc,free 8 #include <cstdlib> // malloc,free 9 9 10 #ifdef TOOLS_MEM 10 #ifdef TOOLS_MEM 11 #include "mem" 11 #include "mem" 12 //#define TOOLS_CSTR_DEBUG_MEM 12 //#define TOOLS_CSTR_DEBUG_MEM 13 #ifdef TOOLS_CSTR_DEBUG_MEM 13 #ifdef TOOLS_CSTR_DEBUG_MEM 14 #include <cstdio> 14 #include <cstdio> 15 #endif 15 #endif 16 #endif 16 #endif 17 17 18 namespace tools { 18 namespace tools { 19 19 20 // NOTE : have str_ to avoid clashes with vari 20 // NOTE : have str_ to avoid clashes with various strxxx cpp macro 21 // that may come from C or system heade 21 // that may come from C or system headers. 22 22 23 #ifdef TOOLS_MEM 23 #ifdef TOOLS_MEM 24 inline const std::string& s_cstr() { 24 inline const std::string& s_cstr() { 25 static const std::string s_v("tools::cstr"); 25 static const std::string s_v("tools::cstr"); 26 return s_v; 26 return s_v; 27 } 27 } 28 #endif 28 #endif 29 29 30 inline char* str_dup(const char* a_cstr 30 inline char* str_dup(const char* a_cstr 31 #ifdef TOOLS_MEM 31 #ifdef TOOLS_MEM 32 ,bool a_inc = true 32 ,bool a_inc = true 33 #endif 33 #endif 34 ) { 34 ) { 35 #ifdef TOOLS_MEM 35 #ifdef TOOLS_MEM 36 if(a_inc) { 36 if(a_inc) { 37 #ifdef TOOLS_CSTR_DEBUG_MEM 37 #ifdef TOOLS_CSTR_DEBUG_MEM 38 ::printf("debug : str_dup \"%s\"\n",a_cstr 38 ::printf("debug : str_dup \"%s\"\n",a_cstr); 39 #endif 39 #endif 40 mem::increment(s_cstr().c_str()); 40 mem::increment(s_cstr().c_str()); 41 } 41 } 42 #endif 42 #endif 43 return ::strcpy((char*)::malloc(::strlen(a_c 43 return ::strcpy((char*)::malloc(::strlen(a_cstr)+1),a_cstr); 44 } 44 } 45 45 46 inline char* str_from_buffer(const char* a_buf 46 inline char* str_from_buffer(const char* a_buffer,size_t a_len 47 #ifdef TOOLS_MEM 47 #ifdef TOOLS_MEM 48 ,bool a_inc = true 48 ,bool a_inc = true 49 #endif 49 #endif 50 ) { 50 ) { 51 #ifdef TOOLS_MEM 51 #ifdef TOOLS_MEM 52 if(a_inc) { 52 if(a_inc) { 53 #ifdef TOOLS_CSTR_DEBUG_MEM 53 #ifdef TOOLS_CSTR_DEBUG_MEM 54 ::printf("debug : str_from_buffer.\n"); 54 ::printf("debug : str_from_buffer.\n"); 55 #endif 55 #endif 56 mem::increment(s_cstr().c_str()); 56 mem::increment(s_cstr().c_str()); 57 } 57 } 58 #endif 58 #endif 59 char* _s = (char*)::malloc(a_len+1); << 59 char* s = (char*)::malloc(a_len+1); 60 if(_s==NULL) return NULL; << 60 if(s==NULL) return NULL; 61 _s = ::strncpy(_s,a_buffer,a_len); << 61 s = ::strncpy(s,a_buffer,a_len); 62 _s[a_len] = 0; << 62 s[a_len] = 0; 63 return _s; << 63 return s; 64 } 64 } 65 65 66 inline void str_del(char*& a_cstr) { 66 inline void str_del(char*& a_cstr) { 67 if(a_cstr==NULL) return; 67 if(a_cstr==NULL) return; 68 #ifdef TOOLS_MEM 68 #ifdef TOOLS_MEM 69 #ifdef TOOLS_CSTR_DEBUG_MEM 69 #ifdef TOOLS_CSTR_DEBUG_MEM 70 ::printf("debug : str_del \"%s\"\n",a_cstr); 70 ::printf("debug : str_del \"%s\"\n",a_cstr); 71 #endif 71 #endif 72 mem::decrement(s_cstr().c_str()); 72 mem::decrement(s_cstr().c_str()); 73 #endif 73 #endif 74 ::free(a_cstr); 74 ::free(a_cstr); 75 a_cstr = NULL; 75 a_cstr = NULL; 76 } 76 } 77 77 78 inline char* str_new(size_t a_l = 0,char a_cha 78 inline char* str_new(size_t a_l = 0,char a_char = ' ') { 79 char* _s = (char*)::malloc((a_l+1)*sizeof(ch << 79 char* s = (char*)::malloc((a_l+1)*sizeof(char)); 80 if(_s==NULL) return NULL; << 80 if(s==NULL) return NULL; 81 #ifdef TOOLS_MEM 81 #ifdef TOOLS_MEM 82 #ifdef TOOLS_CSTR_DEBUG_MEM 82 #ifdef TOOLS_CSTR_DEBUG_MEM 83 ::printf("debug : str_new : len %lu\n",a_l); 83 ::printf("debug : str_new : len %lu\n",a_l); 84 #endif 84 #endif 85 mem::increment(s_cstr().c_str()); 85 mem::increment(s_cstr().c_str()); 86 #endif 86 #endif 87 char* pos = _s; << 87 char* pos = s; 88 for(size_t c=0;c<a_l;c++,pos++) *pos = a_cha 88 for(size_t c=0;c<a_l;c++,pos++) *pos = a_char; 89 *(_s+a_l) = 0; << 89 *(s+a_l) = 0; 90 return _s; << 90 return s; 91 } 91 } 92 92 93 inline bool str_cat(char*& a_1,const char a_c) 93 inline bool str_cat(char*& a_1,const char a_c) { 94 size_t l1 = ::strlen(a_1); 94 size_t l1 = ::strlen(a_1); 95 char* _s = (char*)::malloc(l1+1+1); << 95 char* s = (char*)::malloc(l1+1+1); 96 if(!_s) return false; << 96 if(!s) return false; 97 #ifdef TOOLS_MEM 97 #ifdef TOOLS_MEM 98 #ifdef TOOLS_CSTR_DEBUG_MEM 98 #ifdef TOOLS_CSTR_DEBUG_MEM 99 ::printf("debug : str_cat \"%s\", char %d\n" 99 ::printf("debug : str_cat \"%s\", char %d\n",a_1,a_c); 100 #endif 100 #endif 101 mem::increment(s_cstr().c_str()); 101 mem::increment(s_cstr().c_str()); 102 #endif 102 #endif 103 ::memcpy(_s,a_1,l1); << 103 ::memcpy(s,a_1,l1); 104 ::memcpy(_s+l1,&a_c,1); << 104 ::memcpy(s+l1,&a_c,1); 105 *(_s+l1+1) = 0; << 105 *(s+l1+1) = 0; 106 ::free(a_1); 106 ::free(a_1); 107 #ifdef TOOLS_MEM 107 #ifdef TOOLS_MEM 108 #ifdef TOOLS_CSTR_DEBUG_MEM 108 #ifdef TOOLS_CSTR_DEBUG_MEM 109 ::printf("debug : str_cat : dec\n"); 109 ::printf("debug : str_cat : dec\n"); 110 #endif 110 #endif 111 mem::decrement(s_cstr().c_str()); 111 mem::decrement(s_cstr().c_str()); 112 #endif 112 #endif 113 a_1 = _s; << 113 a_1 = s; 114 return true; 114 return true; 115 } 115 } 116 116 117 inline bool str_cat(char*& a_1,const char* a_2 117 inline bool str_cat(char*& a_1,const char* a_2) { 118 size_t l1 = ::strlen(a_1); 118 size_t l1 = ::strlen(a_1); 119 size_t l2 = ::strlen(a_2); 119 size_t l2 = ::strlen(a_2); 120 char* _s = (char*)::malloc(l1+l2+1); << 120 char* s = (char*)::malloc(l1+l2+1); 121 if(!_s) return false; << 121 if(!s) return false; 122 #ifdef TOOLS_MEM 122 #ifdef TOOLS_MEM 123 #ifdef TOOLS_CSTR_DEBUG_MEM 123 #ifdef TOOLS_CSTR_DEBUG_MEM 124 ::printf("debug : str_cat \"%s\" \"%s\"\n",a 124 ::printf("debug : str_cat \"%s\" \"%s\"\n",a_1,a_2); 125 #endif 125 #endif 126 mem::increment(s_cstr().c_str()); 126 mem::increment(s_cstr().c_str()); 127 #endif 127 #endif 128 ::memcpy(_s,a_1,l1); << 128 ::memcpy(s,a_1,l1); 129 ::memcpy(_s+l1,a_2,l2); << 129 ::memcpy(s+l1,a_2,l2); 130 *(_s+l1+l2) = 0; << 130 *(s+l1+l2) = 0; 131 ::free(a_1); 131 ::free(a_1); 132 #ifdef TOOLS_MEM 132 #ifdef TOOLS_MEM 133 #ifdef TOOLS_CSTR_DEBUG_MEM 133 #ifdef TOOLS_CSTR_DEBUG_MEM 134 ::printf("debug : str_cat : dec\n"); 134 ::printf("debug : str_cat : dec\n"); 135 #endif 135 #endif 136 mem::decrement(s_cstr().c_str()); 136 mem::decrement(s_cstr().c_str()); 137 #endif 137 #endif 138 a_1 = _s; << 138 a_1 = s; 139 return true; 139 return true; 140 } 140 } 141 141 142 inline void str_rev(char* a_s) { 142 inline void str_rev(char* a_s) { 143 size_t l = ::strlen(a_s); 143 size_t l = ::strlen(a_s); 144 size_t hl = l/2; 144 size_t hl = l/2; 145 char* beg = a_s; 145 char* beg = a_s; 146 char* end = a_s+l-1; 146 char* end = a_s+l-1; 147 for(size_t i=0;i<hl;i++) { 147 for(size_t i=0;i<hl;i++) { 148 char c = *end; 148 char c = *end; 149 *end = *beg; 149 *end = *beg; 150 *beg = c; 150 *beg = c; 151 beg++;end--; 151 beg++;end--; 152 } 152 } 153 } 153 } 154 154 155 inline char* str_sub(const char* a_s, 155 inline char* str_sub(const char* a_s, 156 unsigned int a_pos, 156 unsigned int a_pos, 157 unsigned int a_sz = 0) { 157 unsigned int a_sz = 0) { //0 = take up end. 158 size_t l = ::strlen(a_s); 158 size_t l = ::strlen(a_s); 159 if(a_pos>=l) return 0; //throw std::out_of_r 159 if(a_pos>=l) return 0; //throw std::out_of_range 160 size_t ls; 160 size_t ls; 161 if(a_sz) { 161 if(a_sz) { 162 ls = (a_sz<(l-a_pos)?a_sz:(l-a_pos)); //mi 162 ls = (a_sz<(l-a_pos)?a_sz:(l-a_pos)); //min(a_sz,l-a_pos) 163 } else { 163 } else { 164 ls = l-a_pos; 164 ls = l-a_pos; 165 } 165 } 166 char* _s = (char*)::malloc(ls+1); << 166 char* s = (char*)::malloc(ls+1); 167 if(!_s) return 0; << 167 if(!s) return 0; 168 #ifdef TOOLS_MEM 168 #ifdef TOOLS_MEM 169 #ifdef TOOLS_CSTR_DEBUG_MEM 169 #ifdef TOOLS_CSTR_DEBUG_MEM 170 ::printf("debug : str_sub \"%s\"\n",a_s); 170 ::printf("debug : str_sub \"%s\"\n",a_s); 171 #endif 171 #endif 172 mem::increment(s_cstr().c_str()); 172 mem::increment(s_cstr().c_str()); 173 #endif 173 #endif 174 //abcdefgh l=8 174 //abcdefgh l=8 175 //0123456789 175 //0123456789 176 ::memcpy(_s,a_s+a_pos,ls); << 176 ::memcpy(s,a_s+a_pos,ls); 177 *(_s+ls) = 0; << 177 *(s+ls) = 0; 178 return _s; << 178 return s; 179 } 179 } 180 180 181 inline char* str_rep(const char* a_s,unsigned 181 inline char* str_rep(const char* a_s,unsigned int a_pos,unsigned int a_sz,const char* a_new) { 182 //not tested yet. 182 //not tested yet. 183 size_t las = ::strlen(a_s); 183 size_t las = ::strlen(a_s); 184 if(a_pos>=las) return 0; //throw std::out_of 184 if(a_pos>=las) return 0; //throw std::out_of_range 185 if(a_pos+a_sz>las) return 0; 185 if(a_pos+a_sz>las) return 0; 186 size_t lan = ::strlen(a_new); 186 size_t lan = ::strlen(a_new); 187 unsigned int num = a_sz<lan?a_sz:(unsigned i 187 unsigned int num = a_sz<lan?a_sz:(unsigned int)lan; 188 //abcdefghij : l = 10 188 //abcdefghij : l = 10 189 //0123456789 189 //0123456789 190 // p 190 // p 191 size_t le = las-(a_pos+a_sz); 191 size_t le = las-(a_pos+a_sz); 192 size_t ls = a_pos+num+le; 192 size_t ls = a_pos+num+le; 193 char* _s = (char*)::malloc(ls+1); << 193 char* s = (char*)::malloc(ls+1); 194 if(!_s) return 0; << 194 if(!s) return 0; 195 #ifdef TOOLS_MEM 195 #ifdef TOOLS_MEM 196 #ifdef TOOLS_CSTR_DEBUG_MEM 196 #ifdef TOOLS_CSTR_DEBUG_MEM 197 ::printf("debug : str_rep \"%s\"\n",a_s); 197 ::printf("debug : str_rep \"%s\"\n",a_s); 198 #endif 198 #endif 199 mem::increment(s_cstr().c_str()); 199 mem::increment(s_cstr().c_str()); 200 #endif 200 #endif 201 ::memcpy(_s,a_s,a_pos); << 201 ::memcpy(s,a_s,a_pos); 202 ::memcpy(_s+a_pos,a_new,num); << 202 ::memcpy(s+a_pos,a_new,num); 203 if(le) ::memcpy(_s+a_pos+num,a_s+a_pos+a_sz, << 203 if(le) ::memcpy(s+a_pos+num,a_s+a_pos+a_sz,le); 204 *(_s+ls) = 0; << 204 *(s+ls) = 0; 205 return _s; << 205 return s; 206 } 206 } 207 207 208 inline void str_skip(char*& a_cstr,char a_c) { 208 inline void str_skip(char*& a_cstr,char a_c) { 209 while(true) { 209 while(true) { 210 if(*a_cstr!=a_c) break; 210 if(*a_cstr!=a_c) break; 211 a_cstr++; 211 a_cstr++; 212 } 212 } 213 } 213 } 214 214 215 } 215 } 216 216 217 #include <clocale> 217 #include <clocale> 218 218 219 namespace tools { 219 namespace tools { 220 220 221 inline char* beg_LC_NUMERIC() { 221 inline char* beg_LC_NUMERIC() { 222 char* _sl = ::setlocale(LC_NUMERIC,0); 222 char* _sl = ::setlocale(LC_NUMERIC,0); 223 char* old = _sl?str_dup(_sl):0; 223 char* old = _sl?str_dup(_sl):0; 224 ::setlocale(LC_NUMERIC,"C"); 224 ::setlocale(LC_NUMERIC,"C"); 225 return old; 225 return old; 226 } 226 } 227 inline void end_LC_NUMERIC(char*& a_s) { 227 inline void end_LC_NUMERIC(char*& a_s) { 228 if(a_s) { 228 if(a_s) { 229 ::setlocale(LC_NUMERIC,a_s); 229 ::setlocale(LC_NUMERIC,a_s); 230 str_del(a_s); 230 str_del(a_s); 231 } 231 } 232 } 232 } 233 233 234 inline bool str_2d(const char* a_s,double& a_v 234 inline bool str_2d(const char* a_s,double& a_v) { 235 char* olcn = beg_LC_NUMERIC(); 235 char* olcn = beg_LC_NUMERIC(); 236 236 237 char* end; 237 char* end; 238 a_v = ::strtod(a_s,&end); 238 a_v = ::strtod(a_s,&end); 239 if(end==a_s) { 239 if(end==a_s) { 240 a_v = 0; 240 a_v = 0; 241 end_LC_NUMERIC(olcn); 241 end_LC_NUMERIC(olcn); 242 return false; 242 return false; 243 } 243 } 244 244 245 end_LC_NUMERIC(olcn); 245 end_LC_NUMERIC(olcn); 246 return true; 246 return true; 247 } 247 } 248 248 249 /* 249 /* 250 inline bool str_2d(const char* a_s,double& a_v 250 inline bool str_2d(const char* a_s,double& a_v) { 251 char* _sl = ::setlocale(LC_NUMERIC,0); 251 char* _sl = ::setlocale(LC_NUMERIC,0); 252 char* old = _sl?str_dup(_sl):0; 252 char* old = _sl?str_dup(_sl):0; 253 ::setlocale(LC_NUMERIC,"C"); 253 ::setlocale(LC_NUMERIC,"C"); 254 254 255 char* end; 255 char* end; 256 a_v = ::strtod(a_s,&end); 256 a_v = ::strtod(a_s,&end); 257 bool status = true; 257 bool status = true; 258 if(end==a_s) { 258 if(end==a_s) { 259 status = false; 259 status = false; 260 a_v = 0; 260 a_v = 0; 261 } 261 } 262 262 263 if(old) { 263 if(old) { 264 ::setlocale(LC_NUMERIC,old); 264 ::setlocale(LC_NUMERIC,old); 265 str_del(old); 265 str_del(old); 266 } 266 } 267 267 268 return status; 268 return status; 269 } 269 } 270 */ 270 */ 271 271 272 inline size_t str_lcpy(char *dst, const char * 272 inline size_t str_lcpy(char *dst, const char *src, size_t siz) { 273 // Copy src to string dst of size siz. At m 273 // Copy src to string dst of size siz. At most siz-1 characters 274 // will be copied. Always NUL terminates (u 274 // will be copied. Always NUL terminates (unless siz == 0). 275 // Returns strlen(src); if retval >= siz, tr 275 // Returns strlen(src); if retval >= siz, truncation occurred. 276 276 277 // code taken from CERN-ROOT/core/clib to co 277 // code taken from CERN-ROOT/core/clib to compile exlib/tests/h2root.cpp. 278 // strlcpy, strlcat are in string.h on BSD b 278 // strlcpy, strlcat are in string.h on BSD based systems. 279 279 280 // Copyright (c) 1998 Todd C. Miller <Todd.M 280 // Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>. 281 281 282 /*register*/ char* d = dst; 282 /*register*/ char* d = dst; 283 /*register*/ const char* _s = src; << 283 /*register*/ const char* s = src; 284 /*register*/ size_t n = siz; 284 /*register*/ size_t n = siz; 285 285 286 // Copy as many bytes as will fit : 286 // Copy as many bytes as will fit : 287 if (n != 0 && --n != 0) { 287 if (n != 0 && --n != 0) { 288 do { 288 do { 289 if ((*d++ = *_s++) == 0) break; << 289 if ((*d++ = *s++) == 0) break; 290 } while (--n != 0); 290 } while (--n != 0); 291 } 291 } 292 292 293 // Not enough room in dst, add NUL and trave 293 // Not enough room in dst, add NUL and traverse rest of src : 294 if (n == 0) { 294 if (n == 0) { 295 if (siz != 0) *d = '\0'; // NUL-terminate 295 if (siz != 0) *d = '\0'; // NUL-terminate dst. 296 while (*_s++); << 296 while (*s++); 297 } 297 } 298 298 299 return(_s - src - 1); // count does not incl << 299 return(s - src - 1); // count does not include NUL. 300 } 300 } 301 301 302 inline size_t str_lcat(char *dst, const char * 302 inline size_t str_lcat(char *dst, const char *src, size_t siz) { 303 // Appends src to string dst of size siz (un 303 // Appends src to string dst of size siz (unlike strncat, siz is the 304 // full size of dst, not space left). At mo 304 // full size of dst, not space left). At most siz-1 characters 305 // will be copied. Always NUL terminates (u 305 // will be copied. Always NUL terminates (unless siz <= strlen(dst)). 306 // Returns strlen(src) + MIN(siz, strlen(ini 306 // Returns strlen(src) + MIN(siz, strlen(initial dst)). 307 // If retval >= siz, truncation occurred. 307 // If retval >= siz, truncation occurred. 308 308 309 // code taken from CERN-ROOT/core/clib to co 309 // code taken from CERN-ROOT/core/clib to compile exlib/tests/h2root.cpp. 310 // strlcpy, strlcat are in string.h on BSD b 310 // strlcpy, strlcat are in string.h on BSD based systems. 311 311 312 // Copyright (c) 1998 Todd C. Miller <Todd.M 312 // Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>. 313 313 314 /*register*/ char* d = dst; 314 /*register*/ char* d = dst; 315 /*register*/ const char* _s = src; << 315 /*register*/ const char* s = src; 316 /*register*/ size_t n = siz; 316 /*register*/ size_t n = siz; 317 size_t dlen; 317 size_t dlen; 318 318 319 // Find the end of dst and adjust bytes left 319 // Find the end of dst and adjust bytes left but don't go past end : 320 while (n-- != 0 && *d != '\0') d++; 320 while (n-- != 0 && *d != '\0') d++; 321 dlen = d - dst; 321 dlen = d - dst; 322 n = siz - dlen; 322 n = siz - dlen; 323 323 324 if (n == 0) return(dlen + strlen(_s)); << 324 if (n == 0) return(dlen + strlen(s)); 325 325 326 while (*_s != '\0') { << 326 while (*s != '\0') { 327 if (n != 1) { 327 if (n != 1) { 328 *d++ = *_s; << 328 *d++ = *s; 329 n--; 329 n--; 330 } 330 } 331 _s++; << 331 s++; 332 } 332 } 333 *d = '\0'; 333 *d = '\0'; 334 334 335 return(dlen + (_s - src)); // count does not << 335 return(dlen + (s - src)); // count does not include NUL. 336 } 336 } 337 337 338 template <class VECTOR> 338 template <class VECTOR> 339 inline bool str_2ds(char* a_s,const char* a_se 339 inline bool str_2ds(char* a_s,const char* a_sep,VECTOR& a_v) { 340 a_v.clear(); 340 a_v.clear(); 341 const char* tok; 341 const char* tok; 342 double d; 342 double d; 343 for (tok = ::strtok(a_s,a_sep);tok && *tok;t 343 for (tok = ::strtok(a_s,a_sep);tok && *tok;tok = ::strtok(NULL,a_sep)) { 344 if(!str_2d(tok,d)) {a_v.clear();return fal 344 if(!str_2d(tok,d)) {a_v.clear();return false;} 345 a_v.push_back(d); 345 a_v.push_back(d); 346 } 346 } 347 return true; 347 return true; 348 } 348 } 349 349 350 } 350 } 351 351 352 #endif 352 #endif