Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/cstr

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

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