HPCToolkit
tokenize.c
Go to the documentation of this file.
1 // -*-Mode: C++;-*- // technically C99
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 // Simple utility for iterating the tokens out of a given string
48 // FIXME: don't use strtok(), don't use single static buffer,
49 // factor out delimiters, etc.
50 
51 #include <ctype.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <stdbool.h>
56 #include "tokenize.h"
57 
58 #define MIN(a,b) (((a)<=(b))?(a):(b))
59 
60 #define EVENT_DELIMITER '@'
61 #define PREFIX_FREQUENCY 'f'
62 
63 static char *tmp;
64 static char *tk;
65 static char *last;
66 
67 static char *sep1 = " ,;";
68 
69 char *
70 start_tok(char *lst)
71 {
72  tmp = strdup(lst);
73  tk = strtok_r(tmp,sep1,&last);
74  return tk;
75 }
76 
77 int
78 more_tok(void)
79 {
80  if (! tk){
81  free(tmp);
82  }
83  return (tk != NULL);
84 }
85 
86 char *
87 next_tok(void)
88 {
89  tk = strtok_r(NULL,sep1,&last);
90  return tk;
91 }
92 
93 
97 // Returns:
98 // THRESH_FREQ if event has explicit frequency
99 // THRESH_VALUE if event has explicit threshold,
100 // THRESH_DEFAULT if using default.
101 int
103 (
104  const char *input_string,
105  long *threshold,
106  long default_value
107 )
108 {
109  int type = THRESH_VALUE;
110 
111  if (input_string == NULL) {
112  *threshold = default_value;
113  type = THRESH_DEFAULT;
114  } else {
115  if (*input_string == PREFIX_FREQUENCY) {
116  input_string++; // skip the PREFIX_FREQUENCY character
117  type = THRESH_FREQ;
118  } else {
119  type = THRESH_VALUE;
120  }
121 
122  char *endptr;
123  long value = strtol(input_string, &endptr, 10);
124  if (value == 0) {
125  // If there were no digits at all, strtol() stores the original
126  // value of nptr in *endptr. if there were no digits at all, use
127  // the default threshold; otherwise, the value 0 was supplied and
128  // intended.
129  if (endptr == input_string) {
130  value = default_value;
131  if (type == THRESH_FREQ) {
132  // FIXME: Laksono: we have some choices
133  //
134  // Should the type be changed to THRESH_VALUE here?
135  //
136  // Should we just signal an error and quit? Perhaps we are here
137  // because of a typo.
138  }
139  }
140  }
141 
142  *threshold = value;
143  }
144 
145  return type;
146 }
147 
148 // event option syntax is event_name @ [f] threshold
149 // if the f indicator exist, the number is the frequency, otherwise
150 // it's a period number
151 // Returns:
152 // THRESH_FREQ if event has explicit frequency
153 // THRESH_VALUE if event has explicit threshold,
154 // THRESH_DEFAULT if using default.
155 //
156 int
157 hpcrun_extract_ev_thresh(const char *in, int evlen, char *ev, long *th, long def)
158 {
159  unsigned int threshold_pos = 0;
160  unsigned int len = strlen(in);
161 
162  char *dlm = strrchr(in, EVENT_DELIMITER);
163  if (!dlm) {
164  dlm = strrchr(in, ':');
165  }
166  if (dlm) {
167  if (isdigit(dlm[1]) || dlm[1] == PREFIX_FREQUENCY) {
168  // we probably have threshold number
169  len = MIN(dlm - in, evlen);
170  strncpy(ev, in, len);
171  ev[len] = '\0';
172 
173  return hpcrun_extract_threshold(dlm+1+threshold_pos, th, def);
174  }
175  if (dlm[0] == EVENT_DELIMITER) {
176  len = MIN(dlm - in, evlen);
177  }
178  }
179  // no threshold or the threshold is not a number
180  strncpy(ev, in, len);
181  ev[len] = '\0';
182  *th = def;
183 
184  return THRESH_DEFAULT;
185 }
186 
187 //
188 // Check "event" part of candidate string
189 // for an **exact** match event_name
190 //
191 // candidate strings may be either a single event name, or EVENT_NAME@SOMETHING or EVENT_NAME:SOMETHING
192 //
193 bool
194 hpcrun_ev_is(const char* candidate, const char* event_name)
195 {
196  return (strstr(candidate, event_name) == candidate) && strchr("@:",candidate[strlen(event_name)]);
197 }
198 
199 #if TEST_TOKENIZE
200 
201 int
202 main (int argc, char *argv[])
203 {
204  const char *tokens[]={ "one", "two@", "three@3", "four@f4", "five@f", "six@s", "seven::perf",
205  "perf::eight@", "perf::nine@f200", "perf:ten@10" };
206  const int elem = 10;
207  int i, res;
208  long th;
209  char ev[100];
210 
211  for(i=0; i<elem; i++) {
212  res = hpcrun_extract_ev_thresh(tokens[i], 100, ev, &th, -1);
213  printf("%d: %s --> ev: %s, t: %ld, r: %d\n", i, tokens[i], ev, th, res);
214  }
215 }
216 #endif
void MONITOR_EXT_WRAP_NAME() free(void *ptr)
static char * tmp
Definition: tokenize.c:63
#define THRESH_FREQ
Definition: tokenize.h:57
#define MIN(a, b)
Definition: tokenize.c:58
#define EVENT_DELIMITER
Definition: tokenize.c:60
char * next_tok(void)
Definition: tokenize.c:87
#define THRESH_VALUE
Definition: tokenize.h:56
char * start_tok(char *lst)
Definition: tokenize.c:70
static char * tk
Definition: tokenize.c:64
int main(int argc, char *argv[])
Definition: main.cpp:125
static char * sep1
Definition: tokenize.c:67
bool hpcrun_ev_is(const char *candidate, const char *event_name)
Definition: tokenize.c:194
int hpcrun_extract_ev_thresh(const char *in, int evlen, char *ev, long *th, long def)
Definition: tokenize.c:157
#define NULL
Definition: ElfHelper.cpp:85
#define THRESH_DEFAULT
Definition: tokenize.h:55
static int const threshold
#define PREFIX_FREQUENCY
Definition: tokenize.c:61
int hpcrun_extract_threshold(const char *input_string, long *threshold, long default_value)
Definition: tokenize.c:103
static char * last
Definition: tokenize.c:65
int more_tok(void)
Definition: tokenize.c:78