Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
check_expr.c File Reference
#include "asterisk.h"
#include "asterisk/ast_expr.h"
#include "asterisk/inline_api.h"
#include "asterisk/lock.h"
Include dependency graph for check_expr.c:

Go to the source code of this file.

Data Structures

struct  varz
 

Macros

#define AST_API_MODULE   1
 
#define AST_API_MODULE   1
 
#define ASTMM_LIBC   ASTMM_IGNORE
 

Functions

int __ast_bt_get_addresses (struct ast_bt *bt)
 
struct ast_vector_string * __ast_bt_get_symbols (void **addresses, size_t num_frames)
 
int ast_add_profile (const char *x, uint64_t scale)
 support for event profiling More...
 
struct ast_custom_functionast_custom_function_find (const char *name)
 
void ast_log (int level, const char *file, int line, const char *function, const char *fmt,...)
 Used for sending a log message This is the standard logger function. Probably the only way you will invoke it would be something like this: ast_log(AST_LOG_WHATEVER, "Problem with the %s Captain. We should get some more. Will %d be enough?\n", "flux capacitor", 10); where WHATEVER is one of ERROR, DEBUG, EVENT, NOTICE, or WARNING depending on which log you wish to output to. These are implemented as macros, that will provide the function with the needed arguments. More...
 
void ast_mark_lock_acquired (void *)
 Mark the last lock as acquired. More...
 
void ast_remove_lock_info (void *lock_addr, struct ast_bt *bt)
 remove lock info for the current thread More...
 
void ast_restore_lock_info (void *lock_addr)
 
void ast_store_lock_info (enum ast_lock_type type, const char *filename, int line_num, const char *func, const char *lock_name, void *lock_addr, struct ast_bt *bt)
 Store lock info for the current thread. More...
 
void ast_suspend_lock_info (void *lock_addr)
 
int check_eval (char *buffer, char *error_report)
 
unsigned int check_expr (char *buffer, char *error_report)
 
char * find_var (const char *varname)
 
int main (int argc, char **argv)
 
void parse_file (const char *fname)
 
void set_var (const char *varname, const char *varval)
 

Variables

static int global_expr_count =0
 
static int global_expr_max_size =0
 
static int global_expr_tot_size =0
 
static int global_lineno = 1
 
static int global_OK_count =0
 
struct varzglobal_varlist
 
static int global_warn_count =0
 

Macro Definition Documentation

◆ AST_API_MODULE [1/2]

#define AST_API_MODULE   1

Definition at line 31 of file check_expr.c.

◆ AST_API_MODULE [2/2]

#define AST_API_MODULE   1

Definition at line 31 of file check_expr.c.

◆ ASTMM_LIBC

#define ASTMM_LIBC   ASTMM_IGNORE

Definition at line 23 of file check_expr.c.

Function Documentation

◆ __ast_bt_get_addresses()

int __ast_bt_get_addresses ( struct ast_bt bt)

Definition at line 75 of file check_expr.c.

References __ast_bt_get_symbols().

Referenced by ast_remove_lock_info().

76 {
77  /* Suck it, you stupid utils directory! */
78  return 0;
79 }

◆ __ast_bt_get_symbols()

struct ast_vector_string* __ast_bt_get_symbols ( void **  addresses,
size_t  num_frames 
)

Definition at line 81 of file check_expr.c.

References NULL.

Referenced by __ast_bt_get_addresses().

82 {
83  return NULL;
84 }
#define NULL
Definition: resample.c:96

◆ ast_add_profile()

int ast_add_profile ( const char *  x,
uint64_t  scale 
)

support for event profiling

(note, this must be documented a lot more) ast_add_profile allocates a generic 'counter' with a given name, which can be shown with the command 'core show profile <name>'

The counter accumulates positive or negative values supplied by

See also
ast_add_profile(), dividing them by the 'scale' value passed in the create call, and also counts the number of 'events'. Values can also be taked by the TSC counter on ia32 architectures, in which case you can mark the start of an event calling ast_mark(id, 1) and then the end of the event with ast_mark(id, 0). For non-i386 architectures, these two calls return 0.

support for event profiling

Returns
Returns the identifier of the counter.

Definition at line 139 of file check_expr.c.

139 { return 0;}

◆ ast_custom_function_find()

struct ast_custom_function* ast_custom_function_find ( const char *  name)

Definition at line 237 of file check_expr.c.

Referenced by check_expr().

238 {
239  return 0;
240 }

◆ ast_log()

void ast_log ( int  level,
const char *  file,
int  line,
const char *  function,
const char *  fmt,
  ... 
)

Used for sending a log message This is the standard logger function. Probably the only way you will invoke it would be something like this: ast_log(AST_LOG_WHATEVER, "Problem with the %s Captain. We should get some more. Will %d be enough?\n", "flux capacitor", 10); where WHATEVER is one of ERROR, DEBUG, EVENT, NOTICE, or WARNING depending on which log you wish to output to. These are implemented as macros, that will provide the function with the needed arguments.

Parameters
levelType of log event
fileWill be provided by the AST_LOG_* macro
lineWill be provided by the AST_LOG_* macro
functionWill be provided by the AST_LOG_* macro
fmtThis is what is important. The format is the same as your favorite breed of printf. You know how that works, right? :-)

Definition at line 121 of file check_expr.c.

References check_eval(), check_expr(), find_var(), parse_file(), set_var(), varz::varname, and varz::varval.

122 {
123  va_list vars;
124  va_start(vars,fmt);
125 
126  printf("LOG: lev:%d file:%s line:%d func: %s ",
127  level, file, line, function);
128  vprintf(fmt, vars);
129  fflush(stdout);
130  va_end(vars);
131 }

◆ ast_mark_lock_acquired()

void ast_mark_lock_acquired ( void *  foo)

Mark the last lock as acquired.

Definition at line 94 of file check_expr.c.

Referenced by ast_restore_lock_info().

95 {
96  /* not a lot to do in a standalone w/o threading! */
97 }

◆ ast_remove_lock_info()

void ast_remove_lock_info ( void *  lock_addr,
struct ast_bt bt 
)

remove lock info for the current thread

this gets called by ast_mutex_unlock so that information on the lock can be removed from the current thread's lock info struct.

Definition at line 68 of file check_expr.c.

References __ast_bt_get_addresses().

Referenced by ast_store_lock_info().

69 {
70  /* not a lot to do in a standalone w/o threading! */
71 }

◆ ast_restore_lock_info()

void ast_restore_lock_info ( void *  lock_addr)

Definition at line 90 of file check_expr.c.

References ast_mark_lock_acquired().

91 {
92 }

◆ ast_store_lock_info()

void ast_store_lock_info ( enum ast_lock_type  type,
const char *  filename,
int  line_num,
const char *  func,
const char *  lock_name,
void *  lock_addr,
struct ast_bt bt 
)

Store lock info for the current thread.

This function gets called in ast_mutex_lock() and ast_mutex_trylock() so that information about this lock can be stored in this thread's lock info struct. The lock is marked as pending as the thread is waiting on the lock. ast_mark_lock_acquired() will mark it as held by this thread.

Definition at line 61 of file check_expr.c.

References ast_remove_lock_info().

63 {
64  /* not a lot to do in a standalone w/o threading! */
65 }

◆ ast_suspend_lock_info()

void ast_suspend_lock_info ( void *  lock_addr)

Definition at line 87 of file check_expr.c.

88 {
89 }

◆ check_eval()

int check_eval ( char *  buffer,
char *  error_report 
)

Definition at line 242 of file check_expr.c.

References ast_expr(), find_var(), global_lineno, NULL, parse_file(), result, and varz::varname.

Referenced by ast_log(), check_expr(), and parse_file().

243 {
244  char *cp, *ep;
245  char s[4096];
246  char evalbuf[80000];
247  int result;
248 
249  error_report[0] = 0;
250  ep = evalbuf;
251 
252  for (cp=buffer;*cp;cp++) {
253  if (*cp == '$' && *(cp+1) == '{') {
254  int brack_lev = 1;
255  char *xp= cp+2;
256 
257  while (*xp) {
258  if (*xp == '{')
259  brack_lev++;
260  else if (*xp == '}')
261  brack_lev--;
262 
263  if (brack_lev == 0)
264  break;
265  xp++;
266  }
267  if (*xp == '}') {
268  char varname[200];
269  char *val;
270 
271  strncpy(varname,cp+2, xp-cp-2);
272  varname[xp-cp-2] = 0;
273  cp = xp;
274  val = find_var(varname);
275  if (val) {
276  char *z = val;
277  while (*z)
278  *ep++ = *z++;
279  }
280  else {
281  *ep++ = '5'; /* why not */
282  *ep++ = '5';
283  *ep++ = '5';
284  }
285  }
286  else {
287  printf("Unterminated variable reference at line %d\n", global_lineno);
288  *ep++ = *cp;
289  }
290  }
291  else if (*cp == '\\') {
292  /* braindead simple elim of backslash */
293  cp++;
294  *ep++ = *cp;
295  }
296  else
297  *ep++ = *cp;
298  }
299  *ep++ = 0;
300 
301  /* now, run the test */
302  result = ast_expr(evalbuf, s, sizeof(s),NULL);
303  if (result) {
304  sprintf(error_report,"line %d, evaluation of $[ %s ] result: %s\n", global_lineno, evalbuf, s);
305  return 1;
306  } else {
307  sprintf(error_report,"line %d, evaluation of $[ %s ] result: ****SYNTAX ERROR****\n", global_lineno, evalbuf);
308  return 1;
309  }
310 }
Definition: ast_expr2.c:325
char * find_var(const char *varname)
Definition: check_expr.c:141
#define NULL
Definition: resample.c:96
static PGresult * result
Definition: cel_pgsql.c:88
int ast_expr(char *expr, char *buf, int length, struct ast_channel *chan)
Evaluate the given expression.
Definition: ast_expr2f.c:2405
static int global_lineno
Definition: check_expr.c:101

◆ check_expr()

unsigned int check_expr ( char *  buffer,
char *  error_report 
)

Definition at line 165 of file check_expr.c.

References ast_custom_function_find(), check_eval(), global_lineno, global_warn_count, and name.

Referenced by ast_log(), and parse_file().

166 {
167  char* cp;
168  unsigned int warn_found = 0;
169 
170  error_report[0] = 0;
171 
172  for (cp = buffer; *cp; ++cp)
173  {
174  switch (*cp)
175  {
176  case '"':
177  /* skip to the other end */
178  while (*(++cp) && *cp != '"') ;
179 
180  if (*cp == 0)
181  {
182  fprintf(stderr,
183  "Trouble? Unterminated double quote found at line %d\n",
184  global_lineno);
185  }
186  break;
187 
188  case '>':
189  case '<':
190  case '!':
191  if ( (*(cp + 1) == '=')
192  && ( ( (cp > buffer) && (*(cp - 1) != ' ') ) || (*(cp + 2) != ' ') ) )
193  {
194  char msg[200];
195  snprintf(msg,
196  sizeof(msg),
197  "WARNING: line %d: '%c%c' operator not separated by spaces. This may lead to confusion. You may wish to use double quotes to quote the grouping it is in. Please check!\n",
198  global_lineno, *cp, *(cp + 1));
199  strcat(error_report, msg);
201  ++warn_found;
202  }
203  break;
204 
205  case '|':
206  case '&':
207  case '=':
208  case '+':
209  case '-':
210  case '*':
211  case '/':
212  case '%':
213  case '?':
214  case ':':
215  if ( ( (cp > buffer) && (*(cp - 1) != ' ') ) || (*(cp + 1) != ' ') )
216  {
217  char msg[200];
218  snprintf(msg,
219  sizeof(msg),
220  "WARNING: line %d: '%c' operator not separated by spaces. This may lead to confusion. You may wish to use double quotes to quote the grouping it is in. Please check!\n",
221  global_lineno, *cp );
222  strcat(error_report, msg);
224  ++warn_found;
225  }
226  break;
227  }
228  }
229 
230  return warn_found;
231 }
static int global_warn_count
Definition: check_expr.c:105
static int global_lineno
Definition: check_expr.c:101

◆ find_var()

char * find_var ( const char *  varname)

Definition at line 141 of file check_expr.c.

References varz::next, set_var(), varz::varname, and varz::varval.

Referenced by ast_log(), and check_eval().

142 {
143  struct varz *t;
144  for (t= global_varlist; t; t = t->next) {
145  if (!strcmp(t->varname, varname)) {
146  return t->varval;
147  }
148  }
149  return 0;
150 }
char varname[100]
Definition: check_expr.c:110
struct varz * next
Definition: check_expr.c:112
struct varz * global_varlist
Definition: check_expr.c:115
char varval[1000]
Definition: check_expr.c:111

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 406 of file check_expr.c.

References parse_file(), and set_var().

407 {
408  int argc1;
409  char *eq;
410 
411  if (argc < 2) {
412  printf("check_expr -- a program to look thru extensions.conf files for $[...] expressions,\n");
413  printf(" and run them thru the parser, looking for problems\n");
414  printf("Hey-- give me a path to an extensions.conf file!\n");
415  printf(" You can also follow the file path with a series of variable decls,\n");
416  printf(" of the form, varname=value, each separated from the next by spaces.\n");
417  printf(" (this might allow you to avoid division by zero messages, check that math\n");
418  printf(" is being done correctly, etc.)\n");
419  printf(" Note that messages about operators not being surrounded by spaces is merely to alert\n");
420  printf(" you to possible problems where you might be expecting those operators as part of a string.\n");
421  printf(" (to include operators in a string, wrap with double quotes!)\n");
422 
423  exit(19);
424  }
425  global_varlist = 0;
426  for (argc1=2;argc1 < argc; argc1++) {
427  if ((eq = strchr(argv[argc1],'='))) {
428  *eq = 0;
429  set_var(argv[argc1],eq+1);
430  }
431  }
432 
433  /* parse command args for x=y and set varz */
434 
435  parse_file(argv[1]);
436  return 0;
437 }
void set_var(const char *varname, const char *varval)
Definition: check_expr.c:154
struct varz * global_varlist
Definition: check_expr.c:115
void parse_file(const char *fname)
Definition: check_expr.c:315

◆ parse_file()

void parse_file ( const char *  fname)

Definition at line 315 of file check_expr.c.

References check_eval(), check_expr(), global_expr_count, global_expr_max_size, global_expr_tot_size, global_lineno, global_OK_count, global_warn_count, and retval.

Referenced by ast_log(), check_eval(), and main().

316 {
317  FILE *f = fopen(fname,"r");
318  FILE *l = fopen("expr2_log","w");
319  int c1;
320  char last_char= 0;
321  char buffer[30000]; /* I sure hope no expr gets this big! */
322 
323  if (!f) {
324  fprintf(stderr,"Couldn't open %s for reading... need an extensions.conf file to parse!\n",fname);
325  exit(20);
326  }
327  if (!l) {
328  fprintf(stderr,"Couldn't open 'expr2_log' file for writing... please fix and re-run!\n");
329  exit(21);
330  }
331 
332  global_lineno = 1;
333 
334  while ((c1 = fgetc(f)) != EOF) {
335  if (c1 == '\n')
336  global_lineno++;
337  else if (c1 == '[') {
338  if (last_char == '$') {
339  /* bingo, an expr */
340  int bracklev = 1;
341  int bufcount = 0;
342  int retval;
343  char error_report[30000];
344 
345  while ((c1 = fgetc(f)) != EOF) {
346  if (c1 == '[')
347  bracklev++;
348  else if (c1 == ']')
349  bracklev--;
350  if (c1 == '\n') {
351  fprintf(l, "ERROR-- A newline in an expression? Weird! ...at line %d\n", global_lineno);
352  fclose(f);
353  fclose(l);
354  printf("--- ERROR --- A newline in the middle of an expression at line %d!\n", global_lineno);
355  }
356 
357  if (bracklev == 0)
358  break;
359  buffer[bufcount++] = c1;
360  }
361  if (c1 == EOF) {
362  fprintf(l, "ERROR-- End of File Reached in the middle of an Expr at line %d\n", global_lineno);
363  fclose(f);
364  fclose(l);
365  printf("--- ERROR --- EOF reached in middle of an expression at line %d!\n", global_lineno);
366  exit(22);
367  }
368 
369  buffer[bufcount] = 0;
370  /* update stats */
371  global_expr_tot_size += bufcount;
373  if (bufcount > global_expr_max_size)
374  global_expr_max_size = bufcount;
375 
376  retval = check_expr(buffer, error_report); /* check_expr should bump the warning counter */
377  if (retval != 0) {
378  /* print error report */
379  printf("Warning(s) at line %d, expression: $[%s]; see expr2_log file for details\n",
380  global_lineno, buffer);
381  fprintf(l, "%s", error_report);
382  }
383  else {
384  printf("OK -- $[%s] at line %d\n", buffer, global_lineno);
385  global_OK_count++;
386  }
387  error_report[0] = 0;
388  retval = check_eval(buffer, error_report);
389  fprintf(l, "%s", error_report);
390  }
391  }
392  last_char = c1;
393  }
394  printf("Summary:\n Expressions detected: %d\n Expressions OK: %d\n Total # Warnings: %d\n Longest Expr: %d chars\n Ave expr len: %d chars\n",
400 
401  fclose(f);
402  fclose(l);
403 }
static int global_OK_count
Definition: check_expr.c:106
unsigned int check_expr(char *buffer, char *error_report)
Definition: check_expr.c:165
static int global_expr_tot_size
Definition: check_expr.c:104
static int global_warn_count
Definition: check_expr.c:105
int check_eval(char *buffer, char *error_report)
Definition: check_expr.c:242
static int global_expr_count
Definition: check_expr.c:102
static ENTRY retval
Definition: hsearch.c:50
static int global_expr_max_size
Definition: check_expr.c:103
static int global_lineno
Definition: check_expr.c:101

◆ set_var()

void set_var ( const char *  varname,
const char *  varval 
)

Definition at line 154 of file check_expr.c.

References calloc, global_varlist, varz::next, varz::varname, and varz::varval.

Referenced by ast_log(), find_var(), and main().

155 {
156  struct varz *t = (struct varz*)calloc(1,sizeof(struct varz));
157  if (!t)
158  return;
159  strcpy(t->varname, varname);
160  strcpy(t->varval, varval);
161  t->next = global_varlist;
162  global_varlist = t;
163 }
char varname[100]
Definition: check_expr.c:110
struct varz * next
Definition: check_expr.c:112
struct varz * global_varlist
Definition: check_expr.c:115
#define calloc(a, b)
Definition: astmm.h:157
char varval[1000]
Definition: check_expr.c:111

Variable Documentation

◆ global_expr_count

int global_expr_count =0
static

Definition at line 102 of file check_expr.c.

Referenced by parse_file().

◆ global_expr_max_size

int global_expr_max_size =0
static

Definition at line 103 of file check_expr.c.

Referenced by parse_file().

◆ global_expr_tot_size

int global_expr_tot_size =0
static

Definition at line 104 of file check_expr.c.

Referenced by parse_file().

◆ global_lineno

int global_lineno = 1
static

Definition at line 101 of file check_expr.c.

Referenced by check_eval(), check_expr(), and parse_file().

◆ global_OK_count

int global_OK_count =0
static

Definition at line 106 of file check_expr.c.

Referenced by parse_file().

◆ global_varlist

struct varz* global_varlist

Definition at line 115 of file check_expr.c.

Referenced by set_var().

◆ global_warn_count

int global_warn_count =0
static

Definition at line 105 of file check_expr.c.

Referenced by check_expr(), and parse_file().