HPCToolkit
CStrUtil.cpp
Go to the documentation of this file.
1 // -*-Mode: C++;-*-
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL$
6 // $Id$
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2019, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 //****************************************************************************
48 //
49 // File:
50 // $HeadURL$
51 //
52 // Purpose:
53 // [The purpose of this file]
54 //
55 // Description:
56 // [The set of functions, macros, etc. defined in the file]
57 //
58 // Author:
59 //
60 //
61 //****************************************************************************
62 
63 /*************************** System Include Files ***************************/
64 
65 #ifdef NO_STD_CHEADERS
66 # include <stdarg.h>
67 # include <ctype.h>
68 # include <string.h>
69 #else
70 # include <cstdarg>
71 # include <cctype>
72 # include <cstring>
73 using namespace std; // For compatibility with non-std C headers
74 #endif
75 
76 /**************************** User Include Files ****************************/
77 
78 #include "CStrUtil.h"
79 
80 /**************************** Forward Declarations **************************/
81 
82 /****************************************************************************/
83 
84 /* #define STREQ(x,y) ((*(x) == *(y)) && !strcmp((x), (y))) */
85 
86 int
87 STREQ(const char* x, const char* y)
88 {
89  return ((*(x) == *(y)) && !strcmp((x), (y)));
90 }
91 
92 
93 char*
94 ssave(const char* const str)
95 {
96  char* nstr = new char[strlen(str)+1];
97  strcpy(nstr, str);
98  return nstr;
99 }
100 
101 
102 void
103 sfree(char *str)
104 {
105  delete[] str;
106  return;
107 }
108 
109 
110 void
111 smove(char **old, char *fresh)
112 {
113  sfree(*old);
114  *old = ssave(fresh);
115  return;
116 }
117 
118 
119 /*
120  * strcpye - like strcpy, but returns a pointer
121  * to the null that terminates s1.
122  */
123 static char*
124 strcpye(register char* s1, register char* s2)
125 {
126  while ( (*s1++ = *s2++) );
127  return --s1;
128 }
129 
130 
131 /*
132  * nssave(n,s1,...,sn) - concatenate n strings into a dynamically allocated
133  * blob, and return a pointer to the result. "n" must be equal to the # of
134  * strings. The returned pointer should be freed with sfree().
135  */
136 char*
137 nssave(int n, const char* const s1, ...)
138 {
139  va_list ap;
140  int nb = 0; /* the length of the result (bytes to allocate) */
141  char* nstr; /* the result */
142  char* tstr; /* temporary */
143 
144  /* Compute the length of the result */
145  va_start(ap, s1);
146  {
147  nb = strlen(s1);
148  for (int i = 0; i < n-1; i++) nb += strlen(va_arg(ap, char*));
149  }
150  va_end(ap);
151 
152  tstr = new char[nb+1];
153 
154  /* Concat them all together into the new space. */
155  va_start(ap, s1);
156  {
157  char *loc = tstr;
158  loc = strcpye(loc, (char*)s1);
159  for (int i = 0; i < n-1; i++) loc = strcpye(loc, va_arg(ap, char*));
160  }
161  va_end(ap);
162 
163  nstr = ssave(tstr);
164 
165  delete[] tstr;
166 
167  return nstr;
168 }
169 
170 
171 /*
172  * locate the first occurrence of string s2 within s1.
173  * behaves properly for null s1.
174  * returns -1 for no match.
175  */
176 int
177 find(char s1[], char s2[])
178 {
179  int l1, l2, i, j;
180  bool match;
181 
182  l1 = strlen(s1);
183  l2 = strlen(s2);
184  for (i = 0; i <= l1-l2; i++)
185  {
186  match = true;
187  for (j = 0; match && (j < l2); j++) if (s1[i+j] != s2[j]) match = false;
188  if (match) return i;
189  }
190 
191  return -1;
192 }
193 
194 
195 /*
196  * counts occurrences of characters in s2 within s1.
197  */
198 int
199 char_count(char s1[], char s2[])
200 {
201  int l1, l2, i, j, count;
202  char c1;
203 
204  l1 = strlen(s1);
205  l2 = strlen(s2);
206  count = 0;
207  for (i = 0; i < l1; i++)
208  {
209  c1 = s1[i];
210  for (j = 0; j < l2; j++) if (c1 == s2[j]) count++;
211  }
212 
213  return count;
214 }
215 
216 
217 int
218 hash_string(register const char* string, int size)
219 {
220  register unsigned int result = 0;
221 
222  if (*string == '\0')
223  return result; /* no content */
224 
225  const char* stringend = strchr(string, '\0') - 1; /* address of last char */
226  int step = ((stringend - string) >> 2) + 1; /* gives <= 4 samples */
227  while(stringend >= string)
228  {
229  result <<= 7;
230  result |= (*(unsigned char*) stringend) & 0x3F;
231  stringend -= step;
232  }
233 
234  return (result % size);
235 }
236 
237 
238 char*
239 strlower (char *string)
240 {
241  char* s = string;
242  char c;
243 
244  while ((c = *s)) {
245  if (isupper(c)) {
246  *s = (char) tolower(c);
247  }
248  s++;
249  }
250 
251  return string;
252 }
253 
254 
255 char*
256 strupper (char* string)
257 {
258  char* s = string;
259  char c;
260 
261  while ((c = *s)) {
262  if (islower(c)) {
263  *s = (char) toupper(c);
264  }
265  s++;
266  }
267 
268  return string;
269 }
270 
271 
272 char
273 to_lower(char c)
274 {
275  if (isupper(c)) {
276  return (char) tolower(c);
277  }
278  else {
279  return c;
280  }
281 }
282 
283 
284 /* Converts an integer to its ascii representation */
285 void
286 itoa(long n, char a[])
287 {
288  char* aptr;
289 
290  if (n < 0) {
291  a[0] = '-';
292  aptr = a+1;
293  n = -n;
294  }
295  else
296  aptr = a;
297  utoa((unsigned long) n, aptr);
298 }
299 
300 
301 void
302 utoa(unsigned long n, char a[])
303 {
304  char *aptr = a;
305  int i=0;
306  while (n > 0) {
307  aptr[i++] = '0' + n%10;
308  n = n / 10;
309  }
310  if (!i)
311  aptr[i++] = '0';
312 
313  /* swap aptr[] end-for-end */
314  for (int j=0; j<i/2; j++) {
315  aptr[i] = aptr[j];
316  aptr[j] = aptr[i-j-1];
317  aptr[i-j-1] = aptr[i];
318  }
319  aptr[i] = '\0';
320 }
321 
322 
323 /* converts 64 (or less) bit pointers into hex "strings" */
324 void
325 ultohex (unsigned long n, char a[])
326 {
327  int i;
328 
329  a[0] = '0';
330  a[1] = 'x';
331  for (i=2; i<18; i++) {
332  a[i] = '0';
333  }
334  a[18] = '\0';
335 
336  i = 17;
337  do {
338  a[i--] = n % 16 + '0';
339  if ( i<1 ) break; /* ack, why are we running out of space?? */
340  } while ((n /= 16) > 0);
341 }
char * ssave(const char *const str)
Definition: CStrUtil.cpp:94
void sfree(char *str)
Definition: CStrUtil.cpp:103
void itoa(long n, char a[])
Definition: CStrUtil.cpp:286
char * strlower(char *string)
Definition: CStrUtil.cpp:239
int find(char s1[], char s2[])
Definition: CStrUtil.cpp:177
int STREQ(const char *x, const char *y)
Definition: CStrUtil.cpp:87
void utoa(unsigned long n, char a[])
Definition: CStrUtil.cpp:302
int hash_string(register const char *string, int size)
Definition: CStrUtil.cpp:218
char * nssave(int n, const char *const s1,...)
Definition: CStrUtil.cpp:137
void ultohex(unsigned long n, char a[])
Definition: CStrUtil.cpp:325
char to_lower(char c)
Definition: CStrUtil.cpp:273
int char_count(char s1[], char s2[])
Definition: CStrUtil.cpp:199
static char * strcpye(register char *s1, register char *s2)
Definition: CStrUtil.cpp:124
char * strupper(char *string)
Definition: CStrUtil.cpp:256
<!-- ********************************************************************--> n<!-- HPCToolkit Experiment DTD --> n<!-- Version 2.1 --> n<!-- ********************************************************************--> n<!ELEMENT HPCToolkitExperiment(Header,(SecCallPathProfile|SecFlatProfile) *)> n<!ATTLIST HPCToolkitExperiment\n version CDATA #REQUIRED > n n<!-- ******************************************************************--> n n<!-- Info/NV:flexible name-value pairs:(n) ame;(t) ype;(v) alue --> n<!ELEMENT Info(NV *)> n<!ATTLIST Info\n n CDATA #IMPLIED > n<!ELEMENT NV EMPTY > n<!ATTLIST NV\n n CDATA #REQUIRED\n t CDATA #IMPLIED\n v CDATA #REQUIRED > n n<!-- ******************************************************************--> n<!-- Header --> n<!-- ******************************************************************--> n<!ELEMENT Header(Info *)> n<!ATTLIST Header\n n CDATA #REQUIRED > n n<!-- ******************************************************************--> n<!-- Section Header --> n<!-- ******************************************************************--> n<!ELEMENT SecHeader(MetricTable?, MetricDBTable?, TraceDBTable?, LoadModuleTable?, FileTable?, ProcedureTable?, Info *)> n n<!-- MetricTable:--> n<!ELEMENT MetricTable(Metric) * > n n<!-- Metric:(i) d;(n) ame --> n<!--(v) alue-type:transient type of values --> n<!--(t) ype:persistent type of metric --> n<!-- fmt:format;show;--> n<!ELEMENT Metric(MetricFormula *, Info?)> n<!ATTLIST Metric\n i CDATA #REQUIRED\n n CDATA #REQUIRED\n es CDATA #IMPLIED\n em CDATA #IMPLIED\n ep CDATA #IMPLIED\n v(raw|final|derived-incr|derived) \"raw\\ t (inclusive|exclusive|nil) \nil\\ partner CDATA #IMPLIED\ fmt CDATA #IMPLIED\ show (1|0) \1\\ show-percent (1|0) \1> n n<!-- MetricFormula represents derived metrics: (t)ype; (frm): formula --> n<!ELEMENT MetricFormula (Info?)> n<!ATTLIST MetricFormula\ t (combine|finalize) \finalize\\ i CDATA #IMPLIED\ frm CDATA #REQUIRED> n n<!-- Metric data, used in sections: (n)ame [from Metric]; (v)alue --> n<!ELEMENT M EMPTY> n<!ATTLIST M\ n CDATA #REQUIRED\ v CDATA #REQUIRED> n n<!-- MetricDBTable: --> n<!ELEMENT MetricDBTable (MetricDB)*> n n<!-- MetricDB: (i)d; (n)ame --> n<!-- (t)ype: persistent type of metric --> n<!-- db-glob: file glob describing files in metric db --> n<!-- db-id: id within metric db --> n<!-- db-num-metrics: number of metrics in db --> n<!-- db-header-sz: size (in bytes) of a db file header --> n<!ELEMENT MetricDB EMPTY> n<!ATTLIST MetricDB\ i CDATA #REQUIRED\ n CDATA #REQUIRED\ t (inclusive|exclusive|nil) \nil\\ partner CDATA #IMPLIED\ db-glob CDATA #IMPLIED\ db-id CDATA #IMPLIED\ db-num-metrics CDATA #IMPLIED\ db-header-sz CDATA #IMPLIED> n n<!-- TraceDBTable: --> n<!ELEMENT TraceDBTable (TraceDB)> n n<!-- TraceDB: (i)d --> n<!-- db-min-time: min beginning time stamp (global) --> n<!-- db-max-time: max ending time stamp (global) --> n<!ELEMENT TraceDB EMPTY> n<!ATTLIST TraceDB\ i CDATA #REQUIRED\ db-glob CDATA #IMPLIED\ db-min-time CDATA #IMPLIED\ db-max-time CDATA #IMPLIED\ db-header-sz CDATA #IMPLIED> n n<!-- LoadModuleTable assigns a short name to a load module --> n<!ELEMENT LoadModuleTable (LoadModule)*> n n<!ELEMENT LoadModule (Info?)> n<!ATTLIST LoadModule\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!-- FileTable assigns a short name to a file --> n<!ELEMENT FileTable (File)*> n n<!ELEMENT File (Info?)> n<!ATTLIST File\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!-- ProcedureTable assigns a short name to a procedure --> n<!ELEMENT ProcedureTable (Procedure)*> n n<!-- Info/NV: flexible name-value pairs: (n)ame; (t)ype; (v)alue --> n<!-- f: family of the procedure (fake, root, ...)--> n<!ELEMENT Procedure (Info?)> n<!ATTLIST Procedure\ i CDATA #REQUIRED\ n CDATA #REQUIRED\ f CDATA #IMPLIED> n n<!-- ****************************************************************** --> n<!-- Section: Call path profile --> n<!-- ****************************************************************** --> n<!ELEMENT SecCallPathProfile (SecHeader, SecCallPathProfileData)> n<!ATTLIST SecCallPathProfile\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!ELEMENT SecCallPathProfileData (PF|M)*> n<!-- Procedure frame --> n<!-- (i)d: unique identifier for cross referencing --> n<!-- (s)tatic scope id --> n<!-- (n)ame: a string or an id in ProcedureTable --> n<!-- (lm) load module: a string or an id in LoadModuleTable --> n<!-- (f)ile name: a string or an id in LoadModuleTable --> n<!-- (l)ine range: \beg-end\ (inclusive range) --> n<!-- (a)lien: whether frame is alien to enclosing P --> n<!-- (str)uct: hpcstruct node id --> n<!-- (t)ype: hpcrun node type: memory access, variable declaration, ... --> n<!-- (v)ma-range-set: \{[beg-end), [beg-end)...}\ --> n<!ELEMENT PF (PF|Pr|L|C|S|M)*> n<!ATTLIST PF\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ n CDATA #REQUIRED\ lm CDATA #IMPLIED\ f CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Procedure (static): GOAL: replace with 'P' --> n<!ELEMENT Pr (Pr|L|C|S|M)*> n<!ATTLIST Pr\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ n CDATA #REQUIRED\ lm CDATA #IMPLIED\ f CDATA #IMPLIED\ l CDATA #IMPLIED\ a (1|0) \0\\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Callsite (a special StatementRange) --> n<!ELEMENT C (PF|M)*> n<!ATTLIST C\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n n<!-- ****************************************************************** --> n<!-- Section: Flat profile --> n<!-- ****************************************************************** --> n<!ELEMENT SecFlatProfile (SecHeader, SecFlatProfileData)> n<!ATTLIST SecFlatProfile\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!ELEMENT SecFlatProfileData (LM|M)*> n<!-- Load module: (i)d; (n)ame; (v)ma-range-set --> n<!ELEMENT LM (F|P|M)*> n<!ATTLIST LM\ i CDATA #IMPLIED\ n CDATA #REQUIRED\ v CDATA #IMPLIED> n<!-- File --> n<!ELEMENT F (P|L|S|M)*> n<!ATTLIST F\ i CDATA #IMPLIED\ n CDATA #REQUIRED> n<!-- Procedure (Note 1) --> n<!ELEMENT P (P|A|L|S|C|M)*> n<!ATTLIST P\ i CDATA #IMPLIED\ n CDATA #REQUIRED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Alien (Note 1) --> n<!ELEMENT A (A|L|S|C|M)*> n<!ATTLIST A\ i CDATA #IMPLIED\ f CDATA #IMPLIED\ n CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Loop (Note 1,2) --> n<!ELEMENT L (A|Pr|L|S|C|M)*> n<!ATTLIST L\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ f CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Statement (Note 2) --> n<!-- (it): trace record identifier --> n<!ELEMENT S (S|M)*> n<!ATTLIST S\ i CDATA #IMPLIED\ it CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Note 1: Contained Cs may not contain PFs --> n<!-- Note 2: The 's' attribute is not used for flat profiles --> n
void smove(char **old, char *fresh)
Definition: CStrUtil.cpp:111