Merged revisions 52052 via svnmerge from

https://origsvn.digium.com/svn/asterisk/branches/1.4

................
r52052 | murf | 2007-01-24 11:26:22 -0700 (Wed, 24 Jan 2007) | 9 lines

Merged revisions 52002 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.2

........
r52002 | murf | 2007-01-24 10:43:50 -0700 (Wed, 24 Jan 2007) | 1 line

updated check_expr via 8322 (refactoring of expression checking impl); elfring contributed a nice code reorg, I contributed some time to get it working again, better messages
........

................


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@52053 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Steve Murphy
2007-01-24 18:39:49 +00:00
parent 9826fc599b
commit bf0fbdd09b
2 changed files with 96 additions and 64 deletions

View File

@@ -13,7 +13,8 @@
.PHONY: clean all uninstall .PHONY: clean all uninstall
ALL_UTILS:=astman smsq stereorize streamplayer aelparse muted # to get check_expr, add it to the ALL_UTILS list
ALL_UTILS:=astman smsq stereorize streamplayer aelparse muted check_expr
UTILS:=$(ALL_UTILS) UTILS:=$(ALL_UTILS)
include $(ASTTOPDIR)/Makefile.rules include $(ASTTOPDIR)/Makefile.rules
@@ -85,7 +86,7 @@ ast_expr2f.c: ../main/ast_expr2f.c
ast_expr2f.o: ASTCFLAGS+=-DSTANDALONE_AEL -I../main ast_expr2f.o: ASTCFLAGS+=-DSTANDALONE_AEL -I../main
check_expr: check_expr.c ast_expr2.o ast_expr2f.o check_expr: check_expr.o ast_expr2.o ast_expr2f.o
aelbison.c: ../pbx/ael/ael.tab.c aelbison.c: ../pbx/ael/ael.tab.c
@cp $< $@ @cp $< $@

View File

@@ -23,12 +23,12 @@
#include <stdlib.h> #include <stdlib.h>
#include <../include/asterisk/ast_expr.h> #include <../include/asterisk/ast_expr.h>
int global_lineno = 1; static int global_lineno = 1;
int global_expr_count = 0; static int global_expr_count=0;
int global_expr_max_size = 0; static int global_expr_max_size=0;
int global_expr_tot_size = 0; static int global_expr_tot_size=0;
int global_warn_count = 0; static int global_warn_count=0;
int global_OK_count = 0; static int global_OK_count=0;
struct varz struct varz
{ {
@@ -54,6 +54,22 @@ void ast_log(int level, const char *file, int line, const char *function, const
fflush(stdout); fflush(stdout);
va_end(vars); va_end(vars);
} }
void ast_register_file_version(const char *file, const char *version);
void ast_unregister_file_version(const char *file);
char *find_var(const char *varname);
void set_var(const char *varname, const char *varval);
unsigned int check_expr(char* buffer, char* error_report);
int check_eval(char *buffer, char *error_report);
void parse_file(const char *fname);
void ast_register_file_version(const char *file, const char *version)
{
}
void ast_unregister_file_version(const char *file)
{
}
char *find_var(const char *varname) /* the list should be pretty short, if there's any list at all */ char *find_var(const char *varname) /* the list should be pretty short, if there's any list at all */
{ {
@@ -68,7 +84,7 @@ char *find_var(const char *varname) /* the list should be pretty short, if there
void set_var(const char *varname, const char *varval) void set_var(const char *varname, const char *varval)
{ {
struct varz *t = calloc(1,sizeof(struct varz)); struct varz *t = (struct varz*)calloc(1,sizeof(struct varz));
if (!t) if (!t)
return; return;
strcpy(t->varname, varname); strcpy(t->varname, varname);
@@ -77,75 +93,79 @@ void set_var(const char *varname, const char *varval)
global_varlist = t; global_varlist = t;
} }
int check_expr(char *buffer, char *error_report) unsigned int check_expr(char* buffer, char* error_report)
{ {
char *cp; char* cp;
int oplen = 0; unsigned int warn_found = 0;
int warn_found = 0;
error_report[0] = 0; error_report[0] = 0;
for (cp=buffer;*cp;cp++) { for (cp = buffer; *cp; ++cp)
{
if (*cp == '|' switch (*cp)
|| *cp == '&' {
|| *cp == '=' case '"':
|| *cp == '>'
|| *cp == '<'
|| *cp == '+'
|| *cp == '-'
|| *cp == '*'
|| *cp == '/'
|| *cp == '%'
|| *cp == '?'
|| *cp == ':'
/* || *cp == '('
|| *cp == ')' These are pretty hard to track, as they are in funcalls, etc. */
|| *cp == '"') {
if (*cp == '"') {
/* skip to the other end */ /* skip to the other end */
cp++; while (*(++cp) && *cp != '"') ;
while (*cp && *cp != '"')
cp++;
if (*cp == 0) {
fprintf(stderr,"Trouble? Unterminated double quote found at line %d\n",
global_lineno);
}
}
else {
if ((*cp == '>'||*cp == '<' ||*cp=='!') && (*(cp+1) == '=')) {
oplen = 2;
}
else {
oplen = 1;
}
if ((cp > buffer && *(cp-1) != ' ') || *(cp+oplen) != ' ') { if (*cp == 0)
char tbuf[1000]; {
if (oplen == 1) fprintf(stderr,
sprintf(tbuf,"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", "Trouble? Unterminated double quote found at line %d\n",
global_lineno, *cp); global_lineno);
else
sprintf(tbuf,"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",
global_lineno, *cp, *(cp+1));
strcat(error_report,tbuf);
global_warn_count++;
warn_found++;
} }
} break;
case '>':
case '<':
case '!':
if ( (*(cp + 1) == '=')
&& ( ( (cp > buffer) && (*(cp - 1) != ' ') ) || (*(cp + 2) != ' ') ) )
{
char msg[200];
snprintf(msg,
sizeof(msg),
"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",
global_lineno, *cp, *(cp + 1));
strcat(error_report, msg);
++global_warn_count;
++warn_found;
}
break;
case '|':
case '&':
case '=':
case '+':
case '-':
case '*':
case '/':
case '%':
case '?':
case ':':
if ( ( (cp > buffer) && (*(cp - 1) != ' ') ) || (*(cp + 1) != ' ') )
{
char msg[200];
snprintf(msg,
sizeof(msg),
"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",
global_lineno, *cp );
strcat(error_report, msg);
++global_warn_count;
++warn_found;
}
break;
} }
} }
return warn_found; return warn_found;
} }
int check_eval(char *buffer, char *error_report) int check_eval(char *buffer, char *error_report)
{ {
char *cp, *ep, *xp; char *cp, *ep;
char s[4096]; char s[4096];
char evalbuf[80000]; char evalbuf[80000];
int oplen = 0;
int warn_found = 0;
int result; int result;
error_report[0] = 0; error_report[0] = 0;
@@ -221,7 +241,7 @@ void parse_file(const char *fname)
char buffer[30000]; /* I sure hope no expr gets this big! */ char buffer[30000]; /* I sure hope no expr gets this big! */
if (!f) { if (!f) {
fprintf(stderr,"Couldn't open %s for reading... need an extensions.conf file to parse!\n"); fprintf(stderr,"Couldn't open %s for reading... need an extensions.conf file to parse!\n",fname);
exit(20); exit(20);
} }
if (!l) { if (!l) {
@@ -303,13 +323,23 @@ void parse_file(const char *fname)
} }
main(int argc,char **argv) int main(int argc,char **argv)
{ {
int argc1; int argc1;
char *eq; char *eq;
if (argc < 2) { if (argc < 2) {
printf("check_expr -- a program to look thru extensions.conf files for $[...] expressions,\n");
printf(" and run them thru the parser, looking for problems\n");
printf("Hey-- give me a path to an extensions.conf file!\n"); printf("Hey-- give me a path to an extensions.conf file!\n");
printf(" You can also follow the file path with a series of variable decls,\n");
printf(" of the form, varname=value, each separated from the next by spaces.\n");
printf(" (this might allow you to avoid division by zero messages, check that math\n");
printf(" is being done correctly, etc.)\n");
printf(" Note that messages about operators not being surrounded by spaces is merely to alert\n");
printf(" you to possible problems where you might be expecting those operators as part of a string.\n");
printf(" (to include operators in a string, wrap with double quotes!)\n");
exit(19); exit(19);
} }
global_varlist = 0; global_varlist = 0;
@@ -323,4 +353,5 @@ main(int argc,char **argv)
/* parse command args for x=y and set varz */ /* parse command args for x=y and set varz */
parse_file(argv[1]); parse_file(argv[1]);
return 0;
} }