Asterisk - The Open Source Telephony Project GIT-master-7e7a603
Data Structures | Macros | Enumerations | 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
 

Enumerations

enum  ast_lock_type { AST_MUTEX , AST_RDLOCK , AST_WRLOCK }
 

Functions

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...
 
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.

Enumeration Type Documentation

◆ ast_lock_type

Enumerator
AST_MUTEX 
AST_RDLOCK 
AST_WRLOCK 

Definition at line 35 of file check_expr.c.

35 {
39};
@ AST_RDLOCK
Definition: check_expr.c:37
@ AST_WRLOCK
Definition: check_expr.c:38
@ AST_MUTEX
Definition: check_expr.c:36

Function Documentation

◆ 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;}

Referenced by extension_match_core().

◆ ast_custom_function_find()

struct ast_custom_function * ast_custom_function_find ( const char *  name)

◆ 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.

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}

References make_ari_stubs::file.

◆ check_eval()

int check_eval ( char *  buffer,
char *  error_report 
)

Definition at line 242 of file check_expr.c.

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}
int ast_expr(char *expr, char *buf, int length, struct ast_channel *chan)
Evaluate the given expression.
Definition: ast_expr2f.c:2391
static PGresult * result
Definition: cel_pgsql.c:84
static int global_lineno
Definition: check_expr.c:101
char * find_var(const char *varname)
Definition: check_expr.c:141
#define NULL
Definition: resample.c:96
Definition: ast_expr2.c:325

References ast_expr(), find_var(), global_lineno, NULL, and result.

Referenced by parse_file().

◆ check_expr()

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

Definition at line 165 of file check_expr.c.

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",
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

References global_lineno, and global_warn_count.

Referenced by parse_file().

◆ find_var()

char * find_var ( const char *  varname)

Definition at line 141 of file check_expr.c.

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}
struct varz * global_varlist
Definition: check_expr.c:115
char varval[1000]
Definition: check_expr.c:111
struct varz * next
Definition: check_expr.c:112
char varname[100]
Definition: check_expr.c:110

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

Referenced by check_eval().

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 406 of file check_expr.c.

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
void parse_file(const char *fname)
Definition: check_expr.c:315

References global_varlist, parse_file(), and set_var().

◆ parse_file()

void parse_file ( const char *  fname)

Definition at line 315 of file check_expr.c.

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')
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);
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}
unsigned int check_expr(char *buffer, char *error_report)
Definition: check_expr.c:165
int check_eval(char *buffer, char *error_report)
Definition: check_expr.c:242
static int global_expr_tot_size
Definition: check_expr.c:104
static int global_expr_count
Definition: check_expr.c:102
static int global_expr_max_size
Definition: check_expr.c:103
static int global_OK_count
Definition: check_expr.c:106
static ENTRY retval
Definition: hsearch.c:50

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 main().

◆ set_var()

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

Definition at line 154 of file check_expr.c.

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}
#define calloc(a, b)
Definition: astmm.h:155

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

Referenced by main().

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 find_var(), main(), and 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().