FD.io VPP  v19.01.2-3-gf61a1a8
Vector Packet Processing
parse_util.c
Go to the documentation of this file.
1 /*
2  * parse_util.c - halfhearted json parser
3  *
4  * Copyright (c) 2018 Cisco Systems and/or its affiliates
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <perfmon/perfmon.h>
19 #include <vppinfra/unix.h>
20 
21 typedef enum
22 {
27 
28 static u8 *
29 downcase (u8 * s)
30 {
31  u8 *rv = 0;
32  u8 c;
33  int i;
34 
35  for (i = 0; i < vec_len (s); i++)
36  {
37  c = s[i];
38  if (c >= 'A' && c <= 'Z')
39  c = c + ('a' - 'A');
40  vec_add1 (rv, c);
41  }
42  return (rv);
43 }
44 
45 uword *
46 perfmon_parse_table (perfmon_main_t * pm, char *path, char *table_name)
47 {
48  u8 *cp;
49  u8 *event_name;
50  int state = STATE_START;
51  uword *ht;
52  name_value_pair_t *nvp = 0;
53  name_value_pair_t **nvps = 0;
54  u8 *v;
55  int i;
56  u8 *json_filename;
57  clib_error_t *error;
58 
59  /* Create the name/value hash table in any case... */
60  ht = hash_create_string (0, sizeof (uword));
61 
62  json_filename = format (0, "%s/%s%c", path, table_name, 0);
63 
64  vlib_log_debug (pm->log_class, "Try to read perfmon events from %s",
65  json_filename);
66 
67  error = unix_proc_file_contents ((char *) json_filename, &cp);
68 
69  if (error)
70  {
72  "Failed to read CPU-specific counter table %s",
73  json_filename);
75  "Please install the vpp-dev package and then:");
77  (pm->log_class, "cd %s; sudo tar Jxf PerfmonTables.tar.xz", path);
78  vlib_log_err (pm->log_class, "and restart vpp.");
79 
80  vec_free (json_filename);
81  clib_error_report (error);
82  return ht;
83  }
84  vlib_log_debug (pm->log_class, "Read OK, parse the event table...");
85  vec_free (json_filename);
86 
87 again:
88  while (*cp)
89  {
90  switch (state)
91  {
92  case STATE_START:
93  while (*cp && *cp != '{' && *cp != '}' && *cp != ',')
94  cp++;
95  if (*cp == 0)
96  goto done;
97 
98  /* Look for a new event */
99  if (*cp == '{')
100  {
101  if (*cp == 0)
102  {
103  error:
104  clib_warning ("parse fail");
105  hash_free (ht);
106  return 0;
107  }
108  cp++;
109  state = STATE_READ_NAME;
110  goto again;
111  }
112  else if (*cp == '}') /* end of event */
113  {
114  /* Look for the "EventName" nvp */
115  for (i = 0; i < vec_len (nvps); i++)
116  {
117  nvp = nvps[i];
118  if (!strncmp ((char *) nvp->name, "EventName", 9))
119  {
120  event_name = nvp->value;
121  goto found;
122  }
123  }
124  /* no name? */
125  for (i = 0; i < vec_len (nvps); i++)
126  {
127  vec_free (nvps[i]->name);
128  vec_free (nvps[i]->value);
129  }
130  vec_free (nvps);
131  cp++;
132  goto again;
133 
134  found:
135  event_name = downcase (event_name);
136  hash_set_mem (ht, event_name, nvps);
137  nvp = 0;
138  nvps = 0;
139  cp++;
140  goto again;
141  }
142  else if (*cp == ',') /* punctuation */
143  {
144  cp++;
145  goto again;
146  }
147  else /* should never happen... */
148  cp++;
149  goto again;
150 
151  case STATE_READ_NAME:
152  vec_validate (nvp, 0);
153  v = 0;
154  while (*cp && *cp != '"')
155  cp++;
156 
157  if (*cp == 0)
158  {
159  vec_free (nvp);
160  goto error;
161  }
162 
163  cp++;
164  while (*cp && *cp != '"')
165  {
166  vec_add1 (v, *cp);
167  cp++;
168  }
169  if (*cp == 0)
170  {
171  vec_free (v);
172  goto error;
173  }
174  cp++;
175  vec_add1 (v, 0);
176  nvp->name = v;
177  state = STATE_READ_VALUE;
178  goto again;
179 
180  case STATE_READ_VALUE:
181  while (*cp && *cp != ':')
182  cp++;
183  if (*cp == 0)
184  {
185  vec_free (nvp->name);
186  goto error;
187  }
188  while (*cp && *cp != '"')
189  cp++;
190  if (*cp == 0)
191  {
192  vec_free (nvp->name);
193  goto error;
194  }
195  else
196  cp++;
197  v = 0;
198  while (*cp && *cp != '"')
199  {
200  vec_add1 (v, *cp);
201  cp++;
202  }
203  if (*cp == 0)
204  {
205  vec_free (nvp->name);
206  vec_free (v);
207  goto error;
208  }
209  vec_add1 (v, 0);
210  nvp->value = v;
211  vec_add1 (nvps, nvp);
212  while (*cp && *cp != ',' && *cp != '}')
213  cp++;
214  if (*cp == 0)
215  {
216  vec_free (nvp->name);
217  vec_free (nvp->value);
218  goto error;
219  }
220  else if (*cp == '}')
221  state = STATE_START;
222  else
223  {
224  cp++;
225  state = STATE_READ_NAME;
226  }
227  nvp = 0;
228  goto again;
229  }
230  }
231 
232 done:
233  return (ht);
234 }
235 
236 /*
237  * fd.io coding-style-patch-verification: ON
238  *
239  * Local Variables:
240  * eval: (c-set-style "gnu")
241  * End:
242  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:439
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:525
int i
#define hash_set_mem(h, key, value)
Definition: hash.h:275
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
unsigned char u8
Definition: types.h:56
parse_state_t
Definition: parse_util.c:21
vhost_vring_state_t state
Definition: vhost_user.h:120
#define vlib_log_debug(...)
Definition: log.h:54
#define hash_create_string(elts, value_bytes)
Definition: hash.h:690
#define hash_free(h)
Definition: hash.h:310
static u8 * downcase(u8 *s)
Definition: parse_util.c:29
u8 name[64]
Definition: memclnt.api:152
vlib_log_class_t log_class
Definition: perfmon.h:121
svmdb_client_t * c
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
#define clib_warning(format, args...)
Definition: error.h:59
uword * perfmon_parse_table(perfmon_main_t *pm, char *path, char *table_name)
Definition: parse_util.c:46
#define clib_error_report(e)
Definition: error.h:113
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u64 uword
Definition: types.h:112
clib_error_t * unix_proc_file_contents(char *file, u8 **result)
Definition: unix-misc.c:134
#define vlib_log_err(...)
Definition: log.h:50