diff options
author | kpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b> | 2005-08-29 22:03:37 +0000 |
---|---|---|
committer | kpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b> | 2005-08-29 22:03:37 +0000 |
commit | 558f8be1b81fd211756afb3f3814490bfc0763d7 (patch) | |
tree | e6aa0fcc15c7915e5b37a2267d1c36c2c86f0b19 | |
parent | 02052f2d90c56c341514e1b0ed5f62c65f9ea142 (diff) |
don't make expression evaluator allocate a memory buffer for each result
to
be returned; use the buffers already present in the PBX for this purpose
update testexpr2/check_expr to allocate buffers for expression
evaluation
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@6440 f38db490-d61c-443f-a65b-d21fe96a405b
-rwxr-xr-x | .cvsignore | 1 | ||||
-rwxr-xr-x | ast_expr2.c | 13 | ||||
-rwxr-xr-x | ast_expr2.fl | 46 | ||||
-rwxr-xr-x | ast_expr2.y | 13 | ||||
-rwxr-xr-x | ast_expr2f.c | 104 | ||||
-rwxr-xr-x | include/asterisk/ast_expr.h | 26 | ||||
-rwxr-xr-x | pbx.c | 15 | ||||
-rwxr-xr-x | utils/Makefile | 11 | ||||
-rwxr-xr-x | utils/check_expr.c | 13 |
9 files changed, 143 insertions, 99 deletions
diff --git a/.cvsignore b/.cvsignore index 19b9e692a..417f3ff4d 100755 --- a/.cvsignore +++ b/.cvsignore @@ -13,3 +13,4 @@ update.out .tags-sources tags TAGS +testexpr2 diff --git a/ast_expr2.c b/ast_expr2.c index 685276a11..c841616f5 100755 --- a/ast_expr2.c +++ b/ast_expr2.c @@ -1734,7 +1734,7 @@ to_string (struct val *vp) return; } - sprintf (tmp, "%ld", vp->u.i); + sprintf(tmp, "%ld", (long int) vp->u.i); vp->type = AST_EXPR_string; vp->u.s = tmp; } @@ -1775,11 +1775,12 @@ void ast_log(int level, const char *file, int line, const char *function, const int main(int argc,char **argv) { - char *s; - - s=ast_expr(argv[1]); - - printf("=====%s======\n",s); + char s[4096]; + + if (ast_expr(argv[1], s, sizeof(s))) + printf("=====%s======\n",s); + else + printf("No result\n"); } #endif diff --git a/ast_expr2.fl b/ast_expr2.fl index a2282cdbe..39df6013b 100755 --- a/ast_expr2.fl +++ b/ast_expr2.fl @@ -15,6 +15,7 @@ #include <limits.h> #include <asterisk/ast_expr.h> #include <asterisk/logger.h> +#include <asterisk/strings.h> enum valtype { AST_EXPR_integer, AST_EXPR_numeric_string, AST_EXPR_string @@ -41,6 +42,8 @@ struct parse_io yyscan_t scanner; }; +void ast_yyset_column(int column_no, yyscan_t yyscanner); +int ast_yyget_column(yyscan_t yyscanner); %} @@ -90,42 +93,47 @@ struct parse_io ast_yy_scan_string in the .y file, because then, I'd have to define YY_BUFFER_STATE there... UGH! that would be inappropriate. */ -int ast_yyparse( void *); /* need to/should define this prototype for the call to yyparse */ -char *ast_expr(char *arg); /* and this prototype for the following func */ -int ast_yyerror(const char *,YYLTYPE *, struct parse_io *); /* likewise */ +int ast_yyparse(void *); /* need to/should define this prototype for the call to yyparse */ +int ast_yyerror(const char *, YYLTYPE *, struct parse_io *); /* likewise */ -char *ast_expr (char *arg) +int ast_expr(char *expr, char *buf, int length) { struct parse_io *io; - char *pirouni; - io = (struct parse_io *)calloc(sizeof(struct parse_io),1); - io->string = arg; /* to pass to the error routine */ + io = calloc(sizeof(struct parse_io),1); + io->string = expr; /* to pass to the error routine */ ast_yylex_init(&io->scanner); - ast_yy_scan_string(arg,io->scanner); + ast_yy_scan_string(expr, io->scanner); - ast_yyparse ((void *)io); + ast_yyparse ((void *) io); ast_yylex_destroy(io->scanner); - - if (io->val==NULL) { - pirouni=strdup("0"); - return(pirouni); + if (io->val == NULL) { + if (length > 1) { + strcpy(buf, "0"); + return 1; + } } else { if (io->val->type == AST_EXPR_integer) { - pirouni = malloc(24); - sprintf(pirouni, "%ld", io->val->u.i); - } - else { - pirouni=strdup(io->val->u.s); + int res_length; + + res_length = snprintf(buf, length, "%ld", (long int) io->val->u.i); + return res_length <= length ? res_length : length; + } else { +#ifdef STANDALONE + strncpy(buf, io->val->u.s, length - 1); +#else /* !STANDALONE */ + ast_copy_string(buf, io->val->u.s, length); +#endif /* STANDALONE */ + return strlen(buf); } free(io->val); } free(io); - return(pirouni); + return 0; } int ast_yyerror (const char *s, yyltype *loc, struct parse_io *parseio ) diff --git a/ast_expr2.y b/ast_expr2.y index 47a0c7ed1..b25917cc4 100755 --- a/ast_expr2.y +++ b/ast_expr2.y @@ -349,7 +349,7 @@ to_string (struct val *vp) return; } - sprintf (tmp, "%ld", vp->u.i); + sprintf(tmp, "%ld", (long int) vp->u.i); vp->type = AST_EXPR_string; vp->u.s = tmp; } @@ -390,11 +390,12 @@ void ast_log(int level, const char *file, int line, const char *function, const int main(int argc,char **argv) { - char *s; - - s=ast_expr(argv[1]); - - printf("=====%s======\n",s); + char s[4096]; + + if (ast_expr(argv[1], s, sizeof(s))) + printf("=====%s======\n",s); + else + printf("No result\n"); } #endif diff --git a/ast_expr2f.c b/ast_expr2f.c index fce65a2a0..c343c4313 100755 --- a/ast_expr2f.c +++ b/ast_expr2f.c @@ -460,6 +460,7 @@ static yyconst flex_int16_t yy_chk[56] = #include <limits.h> #include <asterisk/ast_expr.h> #include <asterisk/logger.h> +#include <asterisk/strings.h> enum valtype { AST_EXPR_integer, AST_EXPR_numeric_string, AST_EXPR_string @@ -486,8 +487,10 @@ struct parse_io yyscan_t scanner; }; +void ast_yyset_column(int column_no, yyscan_t yyscanner); +int ast_yyget_column(yyscan_t yyscanner); -#line 491 "ast_expr2f.c" +#line 494 "ast_expr2f.c" #define INITIAL 0 @@ -720,10 +723,10 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 55 "ast_expr2.fl" +#line 58 "ast_expr2.fl" -#line 727 "ast_expr2f.c" +#line 730 "ast_expr2f.c" yylval = yylval_param; @@ -808,129 +811,129 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 57 "ast_expr2.fl" +#line 60 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_OR;} YY_BREAK case 2: YY_RULE_SETUP -#line 58 "ast_expr2.fl" +#line 61 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_AND;} YY_BREAK case 3: YY_RULE_SETUP -#line 59 "ast_expr2.fl" +#line 62 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_EQ;} YY_BREAK case 4: YY_RULE_SETUP -#line 60 "ast_expr2.fl" +#line 63 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_GT;} YY_BREAK case 5: YY_RULE_SETUP -#line 61 "ast_expr2.fl" +#line 64 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_LT;} YY_BREAK case 6: YY_RULE_SETUP -#line 62 "ast_expr2.fl" +#line 65 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_GE;} YY_BREAK case 7: YY_RULE_SETUP -#line 63 "ast_expr2.fl" +#line 66 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_LE;} YY_BREAK case 8: YY_RULE_SETUP -#line 64 "ast_expr2.fl" +#line 67 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_NE;} YY_BREAK case 9: YY_RULE_SETUP -#line 65 "ast_expr2.fl" +#line 68 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_PLUS;} YY_BREAK case 10: YY_RULE_SETUP -#line 66 "ast_expr2.fl" +#line 69 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_MINUS;} YY_BREAK case 11: YY_RULE_SETUP -#line 67 "ast_expr2.fl" +#line 70 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_MULT;} YY_BREAK case 12: YY_RULE_SETUP -#line 68 "ast_expr2.fl" +#line 71 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_DIV;} YY_BREAK case 13: YY_RULE_SETUP -#line 69 "ast_expr2.fl" +#line 72 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_MOD;} YY_BREAK case 14: YY_RULE_SETUP -#line 70 "ast_expr2.fl" +#line 73 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_COND;} YY_BREAK case 15: YY_RULE_SETUP -#line 71 "ast_expr2.fl" +#line 74 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_COLON;} YY_BREAK case 16: YY_RULE_SETUP -#line 72 "ast_expr2.fl" +#line 75 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_COLONCOLON;} YY_BREAK case 17: YY_RULE_SETUP -#line 73 "ast_expr2.fl" +#line 76 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_LP;} YY_BREAK case 18: YY_RULE_SETUP -#line 74 "ast_expr2.fl" +#line 77 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_RP;} YY_BREAK case 19: YY_RULE_SETUP -#line 76 "ast_expr2.fl" +#line 79 "ast_expr2.fl" {} YY_BREAK case 20: /* rule 20 can match eol */ YY_RULE_SETUP -#line 77 "ast_expr2.fl" +#line 80 "ast_expr2.fl" {SET_COLUMNS; SET_STRING; return TOKEN;} YY_BREAK case 21: /* rule 21 can match eol */ YY_RULE_SETUP -#line 79 "ast_expr2.fl" +#line 82 "ast_expr2.fl" {/* what to do with eol */} YY_BREAK case 22: YY_RULE_SETUP -#line 80 "ast_expr2.fl" +#line 83 "ast_expr2.fl" { SET_COLUMNS; /* the original behavior of the expression parser was to bring in numbers as a numeric string */ SET_NUMERIC_STRING; return TOKEN;} YY_BREAK case 23: YY_RULE_SETUP -#line 83 "ast_expr2.fl" +#line 86 "ast_expr2.fl" {SET_COLUMNS; SET_STRING; return TOKEN;} YY_BREAK case 24: YY_RULE_SETUP -#line 85 "ast_expr2.fl" +#line 88 "ast_expr2.fl" ECHO; YY_BREAK -#line 934 "ast_expr2f.c" +#line 937 "ast_expr2f.c" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -2068,7 +2071,7 @@ void ast_yyfree (void * ptr , yyscan_t yyscanner) #undef YY_DECL_IS_OURS #undef YY_DECL #endif -#line 85 "ast_expr2.fl" +#line 88 "ast_expr2.fl" @@ -2078,42 +2081,47 @@ void ast_yyfree (void * ptr , yyscan_t yyscanner) ast_yy_scan_string in the .y file, because then, I'd have to define YY_BUFFER_STATE there... UGH! that would be inappropriate. */ -int ast_yyparse( void *); /* need to/should define this prototype for the call to yyparse */ -char *ast_expr(char *arg); /* and this prototype for the following func */ -int ast_yyerror(const char *,YYLTYPE *, struct parse_io *); /* likewise */ +int ast_yyparse(void *); /* need to/should define this prototype for the call to yyparse */ +int ast_yyerror(const char *, YYLTYPE *, struct parse_io *); /* likewise */ -char *ast_expr (char *arg) +int ast_expr(char *expr, char *buf, int length) { struct parse_io *io; - char *pirouni; - io = (struct parse_io *)calloc(sizeof(struct parse_io),1); - io->string = arg; /* to pass to the error routine */ + io = calloc(sizeof(struct parse_io),1); + io->string = expr; /* to pass to the error routine */ ast_yylex_init(&io->scanner); - ast_yy_scan_string(arg,io->scanner); + ast_yy_scan_string(expr, io->scanner); - ast_yyparse ((void *)io); + ast_yyparse ((void *) io); ast_yylex_destroy(io->scanner); - - if (io->val==NULL) { - pirouni=strdup("0"); - return(pirouni); + if (io->val == NULL) { + if (length > 1) { + strcpy(buf, "0"); + return 1; + } } else { if (io->val->type == AST_EXPR_integer) { - pirouni = malloc(24); - sprintf(pirouni, "%ld", io->val->u.i); - } - else { - pirouni=strdup(io->val->u.s); + int res_length; + + res_length = snprintf(buf, length, "%ld", (long int) io->val->u.i); + return res_length <= length ? res_length : length; + } else { +#ifdef STANDALONE + strncpy(buf, io->val->u.s, length - 1); +#else /* !STANDALONE */ + ast_copy_string(buf, io->val->u.s, length); +#endif /* STANDALONE */ + return strlen(buf); } free(io->val); } free(io); - return(pirouni); + return 0; } int ast_yyerror (const char *s, yyltype *loc, struct parse_io *parseio ) diff --git a/include/asterisk/ast_expr.h b/include/asterisk/ast_expr.h index 3739acb7e..c5981a204 100755 --- a/include/asterisk/ast_expr.h +++ b/include/asterisk/ast_expr.h @@ -1 +1,25 @@ -extern char *ast_expr (char *arg); +/* + * Asterisk -- A telephony toolkit for Linux. + * + * Copyright (C) 2005, Digium, Inc. + * + * Mark Spencer <markster@digium.com> + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 + */ + +#ifndef _ASTERISK_EXPR_H +#define _ASTERISK_EXPR_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +int ast_expr(char *expr, char *buf, int length); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* _ASTERISK_EXPR_H */ @@ -1522,19 +1522,12 @@ static void pbx_substitute_variables_helper_full(struct ast_channel *c, const ch vars = var; } - /* Evaluate expression */ - cp4 = ast_expr(vars); - - ast_log(LOG_DEBUG, "Expression is '%s'\n", cp4); - - if (cp4) { - length = strlen(cp4); - if (length > count) - length = count; - memcpy(cp2, cp4, length); + length = ast_expr(vars, cp2, count); + + if (length) { + ast_log(LOG_DEBUG, "Expression result is '%s'\n", cp2); count -= length; cp2 += length; - free(cp4); } } else break; diff --git a/utils/Makefile b/utils/Makefile index 137b0b748..2ee6a5901 100755 --- a/utils/Makefile +++ b/utils/Makefile @@ -40,6 +40,7 @@ install: clean: rm -f *.o astman smsq stereorize check_expr .depend + rm -f ast_expr2.o ast_expr2f.o astman: astman.o ../md5.o $(CC) $(CFLAGS) -o astman astman.o ../md5.o -lnewt @@ -47,8 +48,14 @@ astman: astman.o ../md5.o stereorize: stereorize.o frame.o $(CC) $(CFLAGS) -o stereorize stereorize.o frame.o -lm -check_expr : check_expr.c ../ast_expr.a - $(CC) $(CFLAGS) -o check_expr check_expr.c ../ast_expr.a +ast_expr2.o: ../ast_expr2.c + gcc -g -c -o $@ $< + +ast_expr2f.o: ../ast_expr2f.c + gcc -g -c -DSTANDALONE -o $@ $< + +check_expr: check_expr.c ast_expr2.o ast_expr2f.o + $(CC) $(CFLAGS) -o $@ $^ smsq: smsq.o $(CC) $(CFLAGS) -o smsq ${SOL} smsq.o -lpopt diff --git a/utils/check_expr.c b/utils/check_expr.c index 0814f1dae..89ff155b9 100755 --- a/utils/check_expr.c +++ b/utils/check_expr.c @@ -3,6 +3,7 @@ #include <stdarg.h> #include <string.h> #include <stdlib.h> +#include <../include/asterisk/ast_expr.h> int global_lineno = 1; int global_expr_count = 0; @@ -120,11 +121,12 @@ int check_expr(char *buffer, char *error_report) int check_eval(char *buffer, char *error_report) { - char *cp, *ep, *xp, *s; + char *cp, *ep, *xp; + char s[4096]; char evalbuf[80000]; - extern char *ast_expr(char *); int oplen = 0; int warn_found = 0; + int result; error_report[0] = 0; ep = evalbuf; @@ -179,12 +181,11 @@ int check_eval(char *buffer, char *error_report) *ep++ = 0; /* now, run the test */ - s = ast_expr(evalbuf); - if (s) { + result = ast_expr(evalbuf, s, sizeof(s)); + if (result) { sprintf(error_report,"line %d, evaluation of $[ %s ] result: %s\n", global_lineno, evalbuf, s); return 1; - } - else { + } else { sprintf(error_report,"line %d, evaluation of $[ %s ] result: ****SYNTAX ERROR****\n", global_lineno, evalbuf); return 1; } |