ast_expr2.y 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994
  1. %{
  2. /* Written by Pace Willisson (pace@blitz.com)
  3. * and placed in the public domain.
  4. *
  5. * Largely rewritten by J.T. Conklin (jtc@wimsey.com)
  6. *
  7. * And then overhauled twice by Steve Murphy (murf@e-tools.com)
  8. * to add double-quoted strings, allow mult. spaces, improve
  9. * error messages, and then to fold in a flex scanner for the
  10. * yylex operation.
  11. *
  12. * $FreeBSD: src/bin/expr/expr.y,v 1.16 2000/07/22 10:59:36 se Exp $
  13. */
  14. #include <sys/types.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <locale.h>
  19. #include <ctype.h>
  20. #if !defined(SOLARIS) && !defined(__CYGWIN__)
  21. #include <err.h>
  22. #else
  23. #define quad_t int64_t
  24. #endif
  25. #include <errno.h>
  26. #include <regex.h>
  27. #include <limits.h>
  28. #include <asterisk/ast_expr.h>
  29. #include <asterisk/logger.h>
  30. #if defined(LONG_LONG_MIN) && !defined(QUAD_MIN)
  31. #define QUAD_MIN LONG_LONG_MIN
  32. #endif
  33. #if defined(LONG_LONG_MAX) && !defined(QUAD_MAX)
  34. #define QUAD_MAX LONG_LONG_MAX
  35. #endif
  36. # if ! defined(QUAD_MIN)
  37. # define QUAD_MIN (-0x7fffffffffffffffLL-1)
  38. # endif
  39. # if ! defined(QUAD_MAX)
  40. # define QUAD_MAX (0x7fffffffffffffffLL)
  41. # endif
  42. #define YYPARSE_PARAM parseio
  43. #define YYLEX_PARAM ((struct parse_io *)parseio)->scanner
  44. #define YYERROR_VERBOSE 1
  45. enum valtype {
  46. AST_EXPR_integer, AST_EXPR_numeric_string, AST_EXPR_string
  47. } ;
  48. #ifdef STANDALONE
  49. void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...) __attribute__ ((format (printf,5,6)));
  50. #endif
  51. struct val {
  52. enum valtype type;
  53. union {
  54. char *s;
  55. quad_t i;
  56. } u;
  57. } ;
  58. typedef void *yyscan_t;
  59. struct parse_io
  60. {
  61. char *string;
  62. struct val *val;
  63. yyscan_t scanner;
  64. };
  65. static int chk_div __P((quad_t, quad_t));
  66. static int chk_minus __P((quad_t, quad_t, quad_t));
  67. static int chk_plus __P((quad_t, quad_t, quad_t));
  68. static int chk_times __P((quad_t, quad_t, quad_t));
  69. static void free_value __P((struct val *));
  70. static int is_zero_or_null __P((struct val *));
  71. static int isstring __P((struct val *));
  72. static struct val *make_integer __P((quad_t));
  73. static struct val *make_str __P((const char *));
  74. static struct val *op_and __P((struct val *, struct val *));
  75. static struct val *op_colon __P((struct val *, struct val *));
  76. static struct val *op_eqtilde __P((struct val *, struct val *));
  77. static struct val *op_div __P((struct val *, struct val *));
  78. static struct val *op_eq __P((struct val *, struct val *));
  79. static struct val *op_ge __P((struct val *, struct val *));
  80. static struct val *op_gt __P((struct val *, struct val *));
  81. static struct val *op_le __P((struct val *, struct val *));
  82. static struct val *op_lt __P((struct val *, struct val *));
  83. static struct val *op_cond __P((struct val *, struct val *, struct val *));
  84. static struct val *op_minus __P((struct val *, struct val *));
  85. static struct val *op_negate __P((struct val *));
  86. static struct val *op_compl __P((struct val *));
  87. static struct val *op_ne __P((struct val *, struct val *));
  88. static struct val *op_or __P((struct val *, struct val *));
  89. static struct val *op_plus __P((struct val *, struct val *));
  90. static struct val *op_rem __P((struct val *, struct val *));
  91. static struct val *op_times __P((struct val *, struct val *));
  92. static quad_t to_integer __P((struct val *));
  93. static void to_string __P((struct val *));
  94. /* uh, if I want to predeclare yylex with a YYLTYPE, I have to predeclare the yyltype... sigh */
  95. typedef struct yyltype
  96. {
  97. int first_line;
  98. int first_column;
  99. int last_line;
  100. int last_column;
  101. } yyltype;
  102. # define YYLTYPE yyltype
  103. # define YYLTYPE_IS_TRIVIAL 1
  104. /* we will get warning about no prototype for yylex! But we can't
  105. define it here, we have no definition yet for YYSTYPE. */
  106. int ast_yyerror(const char *,YYLTYPE *, struct parse_io *);
  107. /* I wanted to add args to the yyerror routine, so I could print out
  108. some useful info about the error. Not as easy as it looks, but it
  109. is possible. */
  110. #define ast_yyerror(x) ast_yyerror(x,&yyloc,parseio)
  111. #define DESTROY(x) { \
  112. if ((x)->type == AST_EXPR_numeric_string || (x)->type == AST_EXPR_string) \
  113. free((x)->u.s); \
  114. (x)->u.s = 0; \
  115. free(x); \
  116. }
  117. %}
  118. %pure-parser
  119. %locations
  120. /* %debug for when you are having big problems */
  121. /* %name-prefix="ast_yy" */
  122. %union
  123. {
  124. struct val *val;
  125. }
  126. %{
  127. extern int ast_yylex __P((YYSTYPE *, YYLTYPE *, yyscan_t));
  128. %}
  129. %left <val> TOK_COND TOK_COLONCOLON
  130. %left <val> TOK_OR
  131. %left <val> TOK_AND
  132. %left <val> TOK_EQ TOK_GT TOK_LT TOK_GE TOK_LE TOK_NE
  133. %left <val> TOK_PLUS TOK_MINUS
  134. %left <val> TOK_MULT TOK_DIV TOK_MOD
  135. %right <val> TOK_COMPL
  136. %left <val> TOK_COLON TOK_EQTILDE
  137. %left <val> TOK_RP TOK_LP
  138. %token <val> TOKEN
  139. %type <val> start expr
  140. %%
  141. start: expr { ((struct parse_io *)parseio)->val = (struct val *)calloc(sizeof(struct val),1);
  142. ((struct parse_io *)parseio)->val->type = $1->type;
  143. if( $1->type == AST_EXPR_integer )
  144. ((struct parse_io *)parseio)->val->u.i = $1->u.i;
  145. else
  146. ((struct parse_io *)parseio)->val->u.s = $1->u.s;
  147. free($1);
  148. }
  149. ;
  150. expr: TOKEN { $$= $1;}
  151. | TOK_LP expr TOK_RP { $$ = $2;
  152. @$.first_column = @1.first_column; @$.last_column = @3.last_column;
  153. @$.first_line=0; @$.last_line=0;
  154. DESTROY($1); DESTROY($3); }
  155. | expr TOK_OR expr { $$ = op_or ($1, $3);
  156. DESTROY($2);
  157. @$.first_column = @1.first_column; @$.last_column = @3.last_column;
  158. @$.first_line=0; @$.last_line=0;}
  159. | expr TOK_AND expr { $$ = op_and ($1, $3);
  160. DESTROY($2);
  161. @$.first_column = @1.first_column; @$.last_column = @3.last_column;
  162. @$.first_line=0; @$.last_line=0;}
  163. | expr TOK_EQ expr { $$ = op_eq ($1, $3);
  164. DESTROY($2);
  165. @$.first_column = @1.first_column; @$.last_column = @3.last_column;
  166. @$.first_line=0; @$.last_line=0;}
  167. | expr TOK_GT expr { $$ = op_gt ($1, $3);
  168. DESTROY($2);
  169. @$.first_column = @1.first_column; @$.last_column = @3.last_column;
  170. @$.first_line=0; @$.last_line=0;}
  171. | expr TOK_LT expr { $$ = op_lt ($1, $3);
  172. DESTROY($2);
  173. @$.first_column = @1.first_column; @$.last_column = @3.last_column;
  174. @$.first_line=0; @$.last_line=0;}
  175. | expr TOK_GE expr { $$ = op_ge ($1, $3);
  176. DESTROY($2);
  177. @$.first_column = @1.first_column; @$.last_column = @3.last_column;
  178. @$.first_line=0; @$.last_line=0;}
  179. | expr TOK_LE expr { $$ = op_le ($1, $3);
  180. DESTROY($2);
  181. @$.first_column = @1.first_column; @$.last_column = @3.last_column;
  182. @$.first_line=0; @$.last_line=0;}
  183. | expr TOK_NE expr { $$ = op_ne ($1, $3);
  184. DESTROY($2);
  185. @$.first_column = @1.first_column; @$.last_column = @3.last_column;
  186. @$.first_line=0; @$.last_line=0;}
  187. | expr TOK_PLUS expr { $$ = op_plus ($1, $3);
  188. DESTROY($2);
  189. @$.first_column = @1.first_column; @$.last_column = @3.last_column;
  190. @$.first_line=0; @$.last_line=0;}
  191. | expr TOK_MINUS expr { $$ = op_minus ($1, $3);
  192. DESTROY($2);
  193. @$.first_column = @1.first_column; @$.last_column = @3.last_column;
  194. @$.first_line=0; @$.last_line=0;}
  195. | TOK_MINUS expr %prec TOK_COMPL { $$ = op_negate ($2);
  196. DESTROY($1);
  197. @$.first_column = @1.first_column; @$.last_column = @2.last_column;
  198. @$.first_line=0; @$.last_line=0;}
  199. | TOK_COMPL expr { $$ = op_compl ($2);
  200. DESTROY($1);
  201. @$.first_column = @1.first_column; @$.last_column = @2.last_column;
  202. @$.first_line=0; @$.last_line=0;}
  203. | expr TOK_MULT expr { $$ = op_times ($1, $3);
  204. DESTROY($2);
  205. @$.first_column = @1.first_column; @$.last_column = @3.last_column;
  206. @$.first_line=0; @$.last_line=0;}
  207. | expr TOK_DIV expr { $$ = op_div ($1, $3);
  208. DESTROY($2);
  209. @$.first_column = @1.first_column; @$.last_column = @3.last_column;
  210. @$.first_line=0; @$.last_line=0;}
  211. | expr TOK_MOD expr { $$ = op_rem ($1, $3);
  212. DESTROY($2);
  213. @$.first_column = @1.first_column; @$.last_column = @3.last_column;
  214. @$.first_line=0; @$.last_line=0;}
  215. | expr TOK_COLON expr { $$ = op_colon ($1, $3);
  216. DESTROY($2);
  217. @$.first_column = @1.first_column; @$.last_column = @3.last_column;
  218. @$.first_line=0; @$.last_line=0;}
  219. | expr TOK_EQTILDE expr { $$ = op_eqtilde ($1, $3);
  220. DESTROY($2);
  221. @$.first_column = @1.first_column; @$.last_column = @3.last_column;
  222. @$.first_line=0; @$.last_line=0;}
  223. | expr TOK_COND expr TOK_COLONCOLON expr { $$ = op_cond ($1, $3, $5);
  224. DESTROY($2);
  225. DESTROY($4);
  226. @$.first_column = @1.first_column; @$.last_column = @3.last_column;
  227. @$.first_line=0; @$.last_line=0;}
  228. ;
  229. %%
  230. static struct val *
  231. make_integer (quad_t i)
  232. {
  233. struct val *vp;
  234. vp = (struct val *) malloc (sizeof (*vp));
  235. if (vp == NULL) {
  236. ast_log(LOG_WARNING, "malloc() failed\n");
  237. return(NULL);
  238. }
  239. vp->type = AST_EXPR_integer;
  240. vp->u.i = i;
  241. return vp;
  242. }
  243. static struct val *
  244. make_str (const char *s)
  245. {
  246. struct val *vp;
  247. size_t i;
  248. int isint;
  249. vp = (struct val *) malloc (sizeof (*vp));
  250. if (vp == NULL || ((vp->u.s = strdup (s)) == NULL)) {
  251. ast_log(LOG_WARNING,"malloc() failed\n");
  252. return(NULL);
  253. }
  254. for(i = 1, isint = isdigit(s[0]) || s[0] == '-';
  255. isint && i < strlen(s);
  256. i++)
  257. {
  258. if(!isdigit(s[i]))
  259. isint = 0;
  260. }
  261. if (isint)
  262. vp->type = AST_EXPR_numeric_string;
  263. else
  264. vp->type = AST_EXPR_string;
  265. return vp;
  266. }
  267. static void
  268. free_value (struct val *vp)
  269. {
  270. if (vp==NULL) {
  271. return;
  272. }
  273. if (vp->type == AST_EXPR_string || vp->type == AST_EXPR_numeric_string)
  274. free (vp->u.s);
  275. free(vp);
  276. }
  277. static quad_t
  278. to_integer (struct val *vp)
  279. {
  280. quad_t i;
  281. if (vp == NULL) {
  282. ast_log(LOG_WARNING,"vp==NULL in to_integer()\n");
  283. return(0);
  284. }
  285. if (vp->type == AST_EXPR_integer)
  286. return 1;
  287. if (vp->type == AST_EXPR_string)
  288. return 0;
  289. /* vp->type == AST_EXPR_numeric_string, make it numeric */
  290. errno = 0;
  291. i = strtoll(vp->u.s, (char**)NULL, 10);
  292. if (errno != 0) {
  293. ast_log(LOG_WARNING,"Conversion of %s to integer under/overflowed!\n", vp->u.s);
  294. free(vp->u.s);
  295. vp->u.s = 0;
  296. return(0);
  297. }
  298. free (vp->u.s);
  299. vp->u.i = i;
  300. vp->type = AST_EXPR_integer;
  301. return 1;
  302. }
  303. static void
  304. strip_quotes(struct val *vp)
  305. {
  306. if (vp->type != AST_EXPR_string && vp->type != AST_EXPR_numeric_string)
  307. return;
  308. if( vp->u.s[0] == '"' && vp->u.s[strlen(vp->u.s)-1] == '"' )
  309. {
  310. char *f, *t;
  311. f = vp->u.s;
  312. t = vp->u.s;
  313. while( *f )
  314. {
  315. if( *f && *f != '"' )
  316. *t++ = *f++;
  317. else
  318. f++;
  319. }
  320. *t = *f;
  321. }
  322. }
  323. static void
  324. to_string (struct val *vp)
  325. {
  326. char *tmp;
  327. if (vp->type == AST_EXPR_string || vp->type == AST_EXPR_numeric_string)
  328. return;
  329. tmp = malloc ((size_t)25);
  330. if (tmp == NULL) {
  331. ast_log(LOG_WARNING,"malloc() failed\n");
  332. return;
  333. }
  334. sprintf(tmp, "%ld", (long int) vp->u.i);
  335. vp->type = AST_EXPR_string;
  336. vp->u.s = tmp;
  337. }
  338. static int
  339. isstring (struct val *vp)
  340. {
  341. /* only TRUE if this string is not a valid integer */
  342. return (vp->type == AST_EXPR_string);
  343. }
  344. static int
  345. is_zero_or_null (struct val *vp)
  346. {
  347. if (vp->type == AST_EXPR_integer) {
  348. return (vp->u.i == 0);
  349. } else {
  350. return (*vp->u.s == 0 || (to_integer (vp) && vp->u.i == 0));
  351. }
  352. /* NOTREACHED */
  353. }
  354. #ifdef STANDALONE
  355. void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
  356. {
  357. va_list vars;
  358. va_start(vars,fmt);
  359. printf("LOG: lev:%d file:%s line:%d func: %s ",
  360. level, file, line, function);
  361. vprintf(fmt, vars);
  362. fflush(stdout);
  363. va_end(vars);
  364. }
  365. int main(int argc,char **argv) {
  366. char s[4096];
  367. if (ast_expr(argv[1], s, sizeof(s)))
  368. printf("=====%s======\n",s);
  369. else
  370. printf("No result\n");
  371. }
  372. #endif
  373. #undef ast_yyerror
  374. #define ast_yyerror(x) ast_yyerror(x, YYLTYPE *yylloc, struct parse_io *parseio)
  375. /* I put the ast_yyerror func in the flex input file,
  376. because it refers to the buffer state. Best to
  377. let it access the BUFFER stuff there and not trying
  378. define all the structs, macros etc. in this file! */
  379. static struct val *
  380. op_or (struct val *a, struct val *b)
  381. {
  382. if (is_zero_or_null (a)) {
  383. free_value (a);
  384. return (b);
  385. } else {
  386. free_value (b);
  387. return (a);
  388. }
  389. }
  390. static struct val *
  391. op_and (struct val *a, struct val *b)
  392. {
  393. if (is_zero_or_null (a) || is_zero_or_null (b)) {
  394. free_value (a);
  395. free_value (b);
  396. return (make_integer ((quad_t)0));
  397. } else {
  398. free_value (b);
  399. return (a);
  400. }
  401. }
  402. static struct val *
  403. op_eq (struct val *a, struct val *b)
  404. {
  405. struct val *r;
  406. if (isstring (a) || isstring (b)) {
  407. to_string (a);
  408. to_string (b);
  409. r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) == 0));
  410. } else {
  411. #ifdef DEBUG_FOR_CONVERSIONS
  412. char buffer[2000];
  413. sprintf(buffer,"Converting '%s' and '%s' ", a->u.s, b->u.s);
  414. #endif
  415. (void)to_integer(a);
  416. (void)to_integer(b);
  417. #ifdef DEBUG_FOR_CONVERSIONS
  418. ast_log(LOG_WARNING,"%s to '%lld' and '%lld'\n", buffer, a->u.i, b->u.i);
  419. #endif
  420. r = make_integer ((quad_t)(a->u.i == b->u.i));
  421. }
  422. free_value (a);
  423. free_value (b);
  424. return r;
  425. }
  426. static struct val *
  427. op_gt (struct val *a, struct val *b)
  428. {
  429. struct val *r;
  430. if (isstring (a) || isstring (b)) {
  431. to_string (a);
  432. to_string (b);
  433. r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) > 0));
  434. } else {
  435. (void)to_integer(a);
  436. (void)to_integer(b);
  437. r = make_integer ((quad_t)(a->u.i > b->u.i));
  438. }
  439. free_value (a);
  440. free_value (b);
  441. return r;
  442. }
  443. static struct val *
  444. op_lt (struct val *a, struct val *b)
  445. {
  446. struct val *r;
  447. if (isstring (a) || isstring (b)) {
  448. to_string (a);
  449. to_string (b);
  450. r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) < 0));
  451. } else {
  452. (void)to_integer(a);
  453. (void)to_integer(b);
  454. r = make_integer ((quad_t)(a->u.i < b->u.i));
  455. }
  456. free_value (a);
  457. free_value (b);
  458. return r;
  459. }
  460. static struct val *
  461. op_ge (struct val *a, struct val *b)
  462. {
  463. struct val *r;
  464. if (isstring (a) || isstring (b)) {
  465. to_string (a);
  466. to_string (b);
  467. r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) >= 0));
  468. } else {
  469. (void)to_integer(a);
  470. (void)to_integer(b);
  471. r = make_integer ((quad_t)(a->u.i >= b->u.i));
  472. }
  473. free_value (a);
  474. free_value (b);
  475. return r;
  476. }
  477. static struct val *
  478. op_le (struct val *a, struct val *b)
  479. {
  480. struct val *r;
  481. if (isstring (a) || isstring (b)) {
  482. to_string (a);
  483. to_string (b);
  484. r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) <= 0));
  485. } else {
  486. (void)to_integer(a);
  487. (void)to_integer(b);
  488. r = make_integer ((quad_t)(a->u.i <= b->u.i));
  489. }
  490. free_value (a);
  491. free_value (b);
  492. return r;
  493. }
  494. static struct val *
  495. op_cond (struct val *a, struct val *b, struct val *c)
  496. {
  497. struct val *r;
  498. if( isstring(a) )
  499. {
  500. if( strlen(a->u.s) && strcmp(a->u.s, "\"\"") != 0 && strcmp(a->u.s,"0") != 0 )
  501. {
  502. free_value(a);
  503. free_value(c);
  504. r = b;
  505. }
  506. else
  507. {
  508. free_value(a);
  509. free_value(b);
  510. r = c;
  511. }
  512. }
  513. else
  514. {
  515. (void)to_integer(a);
  516. if( a->u.i )
  517. {
  518. free_value(a);
  519. free_value(c);
  520. r = b;
  521. }
  522. else
  523. {
  524. free_value(a);
  525. free_value(b);
  526. r = c;
  527. }
  528. }
  529. return r;
  530. }
  531. static struct val *
  532. op_ne (struct val *a, struct val *b)
  533. {
  534. struct val *r;
  535. if (isstring (a) || isstring (b)) {
  536. to_string (a);
  537. to_string (b);
  538. r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) != 0));
  539. } else {
  540. (void)to_integer(a);
  541. (void)to_integer(b);
  542. r = make_integer ((quad_t)(a->u.i != b->u.i));
  543. }
  544. free_value (a);
  545. free_value (b);
  546. return r;
  547. }
  548. static int
  549. chk_plus (quad_t a, quad_t b, quad_t r)
  550. {
  551. /* sum of two positive numbers must be positive */
  552. if (a > 0 && b > 0 && r <= 0)
  553. return 1;
  554. /* sum of two negative numbers must be negative */
  555. if (a < 0 && b < 0 && r >= 0)
  556. return 1;
  557. /* all other cases are OK */
  558. return 0;
  559. }
  560. static struct val *
  561. op_plus (struct val *a, struct val *b)
  562. {
  563. struct val *r;
  564. if (!to_integer (a)) {
  565. ast_log(LOG_WARNING,"non-numeric argument\n");
  566. if (!to_integer (b)) {
  567. free_value(a);
  568. free_value(b);
  569. return make_integer(0);
  570. } else {
  571. free_value(a);
  572. return (b);
  573. }
  574. } else if (!to_integer(b)) {
  575. free_value(b);
  576. return (a);
  577. }
  578. r = make_integer (/*(quad_t)*/(a->u.i + b->u.i));
  579. if (chk_plus (a->u.i, b->u.i, r->u.i)) {
  580. ast_log(LOG_WARNING,"overflow\n");
  581. }
  582. free_value (a);
  583. free_value (b);
  584. return r;
  585. }
  586. static int
  587. chk_minus (quad_t a, quad_t b, quad_t r)
  588. {
  589. /* special case subtraction of QUAD_MIN */
  590. if (b == QUAD_MIN) {
  591. if (a >= 0)
  592. return 1;
  593. else
  594. return 0;
  595. }
  596. /* this is allowed for b != QUAD_MIN */
  597. return chk_plus (a, -b, r);
  598. }
  599. static struct val *
  600. op_minus (struct val *a, struct val *b)
  601. {
  602. struct val *r;
  603. if (!to_integer (a)) {
  604. ast_log(LOG_WARNING, "non-numeric argument\n");
  605. if (!to_integer (b)) {
  606. free_value(a);
  607. free_value(b);
  608. return make_integer(0);
  609. } else {
  610. r = make_integer(0 - b->u.i);
  611. free_value(a);
  612. free_value(b);
  613. return (r);
  614. }
  615. } else if (!to_integer(b)) {
  616. ast_log(LOG_WARNING, "non-numeric argument\n");
  617. free_value(b);
  618. return (a);
  619. }
  620. r = make_integer (/*(quad_t)*/(a->u.i - b->u.i));
  621. if (chk_minus (a->u.i, b->u.i, r->u.i)) {
  622. ast_log(LOG_WARNING, "overflow\n");
  623. }
  624. free_value (a);
  625. free_value (b);
  626. return r;
  627. }
  628. static struct val *
  629. op_negate (struct val *a)
  630. {
  631. struct val *r;
  632. if (!to_integer (a) ) {
  633. free_value(a);
  634. ast_log(LOG_WARNING, "non-numeric argument\n");
  635. return make_integer(0);
  636. }
  637. r = make_integer (/*(quad_t)*/(- a->u.i));
  638. if (chk_minus (0, a->u.i, r->u.i)) {
  639. ast_log(LOG_WARNING, "overflow\n");
  640. }
  641. free_value (a);
  642. return r;
  643. }
  644. static struct val *
  645. op_compl (struct val *a)
  646. {
  647. int v1 = 1;
  648. struct val *r;
  649. if( !a )
  650. {
  651. v1 = 0;
  652. }
  653. else
  654. {
  655. switch( a->type )
  656. {
  657. case AST_EXPR_integer:
  658. if( a->u.i == 0 )
  659. v1 = 0;
  660. break;
  661. case AST_EXPR_string:
  662. if( a->u.s == 0 )
  663. v1 = 0;
  664. else
  665. {
  666. if( a->u.s[0] == 0 )
  667. v1 = 0;
  668. else if (strlen(a->u.s) == 1 && a->u.s[0] == '0' )
  669. v1 = 0;
  670. }
  671. break;
  672. case AST_EXPR_numeric_string:
  673. if( a->u.s == 0 )
  674. v1 = 0;
  675. else
  676. {
  677. if( a->u.s[0] == 0 )
  678. v1 = 0;
  679. else if (strlen(a->u.s) == 1 && a->u.s[0] == '0' )
  680. v1 = 0;
  681. }
  682. break;
  683. }
  684. }
  685. r = make_integer (!v1);
  686. free_value (a);
  687. return r;
  688. }
  689. static int
  690. chk_times (quad_t a, quad_t b, quad_t r)
  691. {
  692. /* special case: first operand is 0, no overflow possible */
  693. if (a == 0)
  694. return 0;
  695. /* cerify that result of division matches second operand */
  696. if (r / a != b)
  697. return 1;
  698. return 0;
  699. }
  700. static struct val *
  701. op_times (struct val *a, struct val *b)
  702. {
  703. struct val *r;
  704. if (!to_integer (a) || !to_integer (b)) {
  705. free_value(a);
  706. free_value(b);
  707. ast_log(LOG_WARNING, "non-numeric argument\n");
  708. return(make_integer(0));
  709. }
  710. r = make_integer (/*(quad_t)*/(a->u.i * b->u.i));
  711. if (chk_times (a->u.i, b->u.i, r->u.i)) {
  712. ast_log(LOG_WARNING, "overflow\n");
  713. }
  714. free_value (a);
  715. free_value (b);
  716. return (r);
  717. }
  718. static int
  719. chk_div (quad_t a, quad_t b)
  720. {
  721. /* div by zero has been taken care of before */
  722. /* only QUAD_MIN / -1 causes overflow */
  723. if (a == QUAD_MIN && b == -1)
  724. return 1;
  725. /* everything else is OK */
  726. return 0;
  727. }
  728. static struct val *
  729. op_div (struct val *a, struct val *b)
  730. {
  731. struct val *r;
  732. if (!to_integer (a)) {
  733. free_value(a);
  734. free_value(b);
  735. ast_log(LOG_WARNING, "non-numeric argument\n");
  736. return make_integer(0);
  737. } else if (!to_integer (b)) {
  738. free_value(a);
  739. free_value(b);
  740. ast_log(LOG_WARNING, "non-numeric argument\n");
  741. return make_integer(INT_MAX);
  742. }
  743. if (b->u.i == 0) {
  744. ast_log(LOG_WARNING, "division by zero\n");
  745. free_value(a);
  746. free_value(b);
  747. return make_integer(INT_MAX);
  748. }
  749. r = make_integer (/*(quad_t)*/(a->u.i / b->u.i));
  750. if (chk_div (a->u.i, b->u.i)) {
  751. ast_log(LOG_WARNING, "overflow\n");
  752. }
  753. free_value (a);
  754. free_value (b);
  755. return r;
  756. }
  757. static struct val *
  758. op_rem (struct val *a, struct val *b)
  759. {
  760. struct val *r;
  761. if (!to_integer (a) || !to_integer (b)) {
  762. ast_log(LOG_WARNING, "non-numeric argument\n");
  763. free_value(a);
  764. free_value(b);
  765. return make_integer(0);
  766. }
  767. if (b->u.i == 0) {
  768. ast_log(LOG_WARNING, "div by zero\n");
  769. free_value(a);
  770. return(b);
  771. }
  772. r = make_integer (/*(quad_t)*/(a->u.i % b->u.i));
  773. /* chk_rem necessary ??? */
  774. free_value (a);
  775. free_value (b);
  776. return r;
  777. }
  778. static struct val *
  779. op_colon (struct val *a, struct val *b)
  780. {
  781. regex_t rp;
  782. regmatch_t rm[2];
  783. char errbuf[256];
  784. int eval;
  785. struct val *v;
  786. /* coerce to both arguments to strings */
  787. to_string(a);
  788. to_string(b);
  789. /* strip double quotes from both -- they'll screw up the pattern, and the search string starting at ^ */
  790. strip_quotes(a);
  791. strip_quotes(b);
  792. /* compile regular expression */
  793. if ((eval = regcomp (&rp, b->u.s, REG_EXTENDED)) != 0) {
  794. regerror (eval, &rp, errbuf, sizeof(errbuf));
  795. ast_log(LOG_WARNING,"regcomp() error : %s",errbuf);
  796. free_value(a);
  797. free_value(b);
  798. return make_str("");
  799. }
  800. /* compare string against pattern */
  801. /* remember that patterns are anchored to the beginning of the line */
  802. if (regexec(&rp, a->u.s, (size_t)2, rm, 0) == 0 && rm[0].rm_so == 0) {
  803. if (rm[1].rm_so >= 0) {
  804. *(a->u.s + rm[1].rm_eo) = '\0';
  805. v = make_str (a->u.s + rm[1].rm_so);
  806. } else {
  807. v = make_integer ((quad_t)(rm[0].rm_eo - rm[0].rm_so));
  808. }
  809. } else {
  810. if (rp.re_nsub == 0) {
  811. v = make_integer ((quad_t)0);
  812. } else {
  813. v = make_str ("");
  814. }
  815. }
  816. /* free arguments and pattern buffer */
  817. free_value (a);
  818. free_value (b);
  819. regfree (&rp);
  820. return v;
  821. }
  822. static struct val *
  823. op_eqtilde (struct val *a, struct val *b)
  824. {
  825. regex_t rp;
  826. regmatch_t rm[2];
  827. char errbuf[256];
  828. int eval;
  829. struct val *v;
  830. /* coerce to both arguments to strings */
  831. to_string(a);
  832. to_string(b);
  833. /* strip double quotes from both -- they'll screw up the pattern, and the search string starting at ^ */
  834. strip_quotes(a);
  835. strip_quotes(b);
  836. /* compile regular expression */
  837. if ((eval = regcomp (&rp, b->u.s, REG_EXTENDED)) != 0) {
  838. regerror (eval, &rp, errbuf, sizeof(errbuf));
  839. ast_log(LOG_WARNING,"regcomp() error : %s",errbuf);
  840. free_value(a);
  841. free_value(b);
  842. return make_str("");
  843. }
  844. /* compare string against pattern */
  845. /* remember that patterns are anchored to the beginning of the line */
  846. if (regexec(&rp, a->u.s, (size_t)2, rm, 0) == 0 ) {
  847. if (rm[1].rm_so >= 0) {
  848. *(a->u.s + rm[1].rm_eo) = '\0';
  849. v = make_str (a->u.s + rm[1].rm_so);
  850. } else {
  851. v = make_integer ((quad_t)(rm[0].rm_eo - rm[0].rm_so));
  852. }
  853. } else {
  854. if (rp.re_nsub == 0) {
  855. v = make_integer ((quad_t)0);
  856. } else {
  857. v = make_str ("");
  858. }
  859. }
  860. /* free arguments and pattern buffer */
  861. free_value (a);
  862. free_value (b);
  863. regfree (&rp);
  864. return v;
  865. }