ast_expr.y 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  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. * $FreeBSD: src/bin/expr/expr.y,v 1.16 2000/07/22 10:59:36 se Exp $
  8. */
  9. #include <sys/types.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <locale.h>
  14. #include <ctype.h>
  15. #include <err.h>
  16. #include <errno.h>
  17. #include <regex.h>
  18. #include <limits.h>
  19. #include <asterisk/ast_expr.h>
  20. #include <asterisk/logger.h>
  21. # if ! defined(QUAD_MIN)
  22. # define QUAD_MIN (-0x7fffffffffffffffL-1)
  23. # endif
  24. # if ! defined(QUAD_MAX)
  25. # define QUAD_MAX (0x7fffffffffffffffL)
  26. # endif
  27. #define YYPARSE_PARAM kota
  28. #define YYLEX_PARAM kota
  29. /* #define ast_log fprintf
  30. #define LOG_WARNING stderr */
  31. enum valtype {
  32. integer, numeric_string, string
  33. } ;
  34. struct val {
  35. enum valtype type;
  36. union {
  37. char *s;
  38. quad_t i;
  39. } u;
  40. } ;
  41. struct parser_control {
  42. struct val *result;
  43. int pipa;
  44. char *argv;
  45. char *ptrptr;
  46. int firsttoken;
  47. } ;
  48. static int chk_div __P((quad_t, quad_t));
  49. static int chk_minus __P((quad_t, quad_t, quad_t));
  50. static int chk_plus __P((quad_t, quad_t, quad_t));
  51. static int chk_times __P((quad_t, quad_t, quad_t));
  52. static void free_value __P((struct val *));
  53. static int is_zero_or_null __P((struct val *));
  54. static int isstring __P((struct val *));
  55. static struct val *make_integer __P((quad_t));
  56. static struct val *make_str __P((const char *));
  57. static struct val *op_and __P((struct val *, struct val *));
  58. static struct val *op_colon __P((struct val *, struct val *));
  59. static struct val *op_div __P((struct val *, struct val *));
  60. static struct val *op_eq __P((struct val *, struct val *));
  61. static struct val *op_ge __P((struct val *, struct val *));
  62. static struct val *op_gt __P((struct val *, struct val *));
  63. static struct val *op_le __P((struct val *, struct val *));
  64. static struct val *op_lt __P((struct val *, struct val *));
  65. static struct val *op_minus __P((struct val *, struct val *));
  66. static struct val *op_ne __P((struct val *, struct val *));
  67. static struct val *op_or __P((struct val *, struct val *));
  68. static struct val *op_plus __P((struct val *, struct val *));
  69. static struct val *op_rem __P((struct val *, struct val *));
  70. static struct val *op_times __P((struct val *, struct val *));
  71. static quad_t to_integer __P((struct val *));
  72. static void to_string __P((struct val *));
  73. static int ast_yyerror __P((const char *));
  74. %}
  75. %pure-parser
  76. /* %name-prefix="ast_yy" */
  77. %union
  78. {
  79. struct val *val;
  80. }
  81. %{
  82. static int ast_yylex __P((YYSTYPE *, struct parser_control *));
  83. %}
  84. %left <val> '|'
  85. %left <val> '&'
  86. %left <val> '=' '>' '<' GE LE NE
  87. %left <val> '+' '-'
  88. %left <val> '*' '/' '%'
  89. %left <val> ':'
  90. %token <val> TOKEN
  91. %type <val> start expr
  92. %%
  93. start: expr { ((struct parser_control *)kota)->result = $$; }
  94. ;
  95. expr: TOKEN
  96. | '(' expr ')' { $$ = $2; }
  97. | expr '|' expr { $$ = op_or ($1, $3); }
  98. | expr '&' expr { $$ = op_and ($1, $3); }
  99. | expr '=' expr { $$ = op_eq ($1, $3); }
  100. | expr '>' expr { $$ = op_gt ($1, $3); }
  101. | expr '<' expr { $$ = op_lt ($1, $3); }
  102. | expr GE expr { $$ = op_ge ($1, $3); }
  103. | expr LE expr { $$ = op_le ($1, $3); }
  104. | expr NE expr { $$ = op_ne ($1, $3); }
  105. | expr '+' expr { $$ = op_plus ($1, $3); }
  106. | expr '-' expr { $$ = op_minus ($1, $3); }
  107. | expr '*' expr { $$ = op_times ($1, $3); }
  108. | expr '/' expr { $$ = op_div ($1, $3); }
  109. | expr '%' expr { $$ = op_rem ($1, $3); }
  110. | expr ':' expr { $$ = op_colon ($1, $3); }
  111. ;
  112. %%
  113. static struct val *
  114. make_integer (i)
  115. quad_t i;
  116. {
  117. struct val *vp;
  118. vp = (struct val *) malloc (sizeof (*vp));
  119. if (vp == NULL) {
  120. ast_log(LOG_WARNING, "malloc() failed\n");
  121. return(NULL);
  122. }
  123. vp->type = integer;
  124. vp->u.i = i;
  125. return vp;
  126. }
  127. static struct val *
  128. make_str (s)
  129. const char *s;
  130. {
  131. struct val *vp;
  132. size_t i;
  133. int isint;
  134. vp = (struct val *) malloc (sizeof (*vp));
  135. if (vp == NULL || ((vp->u.s = strdup (s)) == NULL)) {
  136. ast_log(LOG_WARNING,"malloc() failed\n");
  137. return(NULL);
  138. }
  139. for(i = 1, isint = isdigit(s[0]) || s[0] == '-';
  140. isint && i < strlen(s);
  141. i++)
  142. {
  143. if(!isdigit(s[i]))
  144. isint = 0;
  145. }
  146. if (isint)
  147. vp->type = numeric_string;
  148. else
  149. vp->type = string;
  150. return vp;
  151. }
  152. static void
  153. free_value (vp)
  154. struct val *vp;
  155. {
  156. if (vp==NULL) {
  157. return;
  158. }
  159. if (vp->type == string || vp->type == numeric_string)
  160. free (vp->u.s);
  161. }
  162. static quad_t
  163. to_integer (vp)
  164. struct val *vp;
  165. {
  166. quad_t i;
  167. if (vp == NULL) {
  168. ast_log(LOG_WARNING,"vp==NULL in to_integer()\n");
  169. return(0);
  170. }
  171. if (vp->type == integer)
  172. return 1;
  173. if (vp->type == string)
  174. return 0;
  175. /* vp->type == numeric_string, make it numeric */
  176. errno = 0;
  177. i = strtoq(vp->u.s, (char**)NULL, 10);
  178. if (errno != 0) {
  179. free(vp->u.s);
  180. ast_log(LOG_WARNING,"overflow\n");
  181. return(0);
  182. }
  183. free (vp->u.s);
  184. vp->u.i = i;
  185. vp->type = integer;
  186. return 1;
  187. }
  188. static void
  189. to_string (vp)
  190. struct val *vp;
  191. {
  192. char *tmp;
  193. if (vp->type == string || vp->type == numeric_string)
  194. return;
  195. tmp = malloc ((size_t)25);
  196. if (tmp == NULL) {
  197. ast_log(LOG_WARNING,"malloc() failed\n");
  198. return;
  199. }
  200. sprintf (tmp, "%lld", (long long)vp->u.i);
  201. vp->type = string;
  202. vp->u.s = tmp;
  203. }
  204. static int
  205. isstring (vp)
  206. struct val *vp;
  207. {
  208. /* only TRUE if this string is not a valid integer */
  209. return (vp->type == string);
  210. }
  211. static int
  212. ast_yylex (YYSTYPE *lvalp, struct parser_control *karoto)
  213. {
  214. char *p;
  215. if (karoto->firsttoken==1) {
  216. p=strtok_r(karoto->argv," ",&(karoto->ptrptr));
  217. karoto->firsttoken=0;
  218. } else {
  219. p=strtok_r(NULL," ",&(karoto->ptrptr));
  220. }
  221. if (p==NULL) {
  222. return (0);
  223. }
  224. if (strlen (p) == 1) {
  225. if (strchr ("|&=<>+-*/%:()", *p))
  226. return (*p);
  227. } else if (strlen (p) == 2 && p[1] == '=') {
  228. switch (*p) {
  229. case '>': return (GE);
  230. case '<': return (LE);
  231. case '!': return (NE);
  232. }
  233. }
  234. lvalp->val = make_str (p);
  235. return (TOKEN);
  236. }
  237. static int
  238. is_zero_or_null (vp)
  239. struct val *vp;
  240. {
  241. if (vp->type == integer) {
  242. return (vp->u.i == 0);
  243. } else {
  244. return (*vp->u.s == 0 || (to_integer (vp) && vp->u.i == 0));
  245. }
  246. /* NOTREACHED */
  247. }
  248. char *ast_expr (char *arg)
  249. {
  250. struct parser_control karoto;
  251. char *kota;
  252. char *pirouni;
  253. kota=strdup(arg);
  254. karoto.result = NULL;
  255. karoto.firsttoken=1;
  256. karoto.argv=kota;
  257. ast_yyparse ((void *)&karoto);
  258. free(kota);
  259. if (karoto.result==NULL) {
  260. pirouni=strdup("0");
  261. return(pirouni);
  262. } else {
  263. if (karoto.result->type == integer) {
  264. pirouni=malloc(256);
  265. sprintf (pirouni,"%lld", (long long)karoto.result->u.i);
  266. }
  267. else {
  268. pirouni=strdup(karoto.result->u.s);
  269. }
  270. free(karoto.result);
  271. }
  272. return(pirouni);
  273. }
  274. #ifdef STANDALONE
  275. int main(int argc,char **argv) {
  276. char *s;
  277. s=ast_expr(argv[1]);
  278. printf("=====%s======\n",s);
  279. }
  280. #endif
  281. static int
  282. ast_yyerror (s)
  283. const char *s;
  284. {
  285. ast_log(LOG_WARNING,"ast_yyerror(): syntax error: %s\n",s);
  286. return(0);
  287. }
  288. static struct val *
  289. op_or (a, b)
  290. struct val *a, *b;
  291. {
  292. if (is_zero_or_null (a)) {
  293. free_value (a);
  294. return (b);
  295. } else {
  296. free_value (b);
  297. return (a);
  298. }
  299. }
  300. static struct val *
  301. op_and (a, b)
  302. struct val *a, *b;
  303. {
  304. if (is_zero_or_null (a) || is_zero_or_null (b)) {
  305. free_value (a);
  306. free_value (b);
  307. return (make_integer ((quad_t)0));
  308. } else {
  309. free_value (b);
  310. return (a);
  311. }
  312. }
  313. static struct val *
  314. op_eq (a, b)
  315. struct val *a, *b;
  316. {
  317. struct val *r;
  318. if (isstring (a) || isstring (b)) {
  319. to_string (a);
  320. to_string (b);
  321. r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) == 0));
  322. } else {
  323. (void)to_integer(a);
  324. (void)to_integer(b);
  325. r = make_integer ((quad_t)(a->u.i == b->u.i));
  326. }
  327. free_value (a);
  328. free_value (b);
  329. return r;
  330. }
  331. static struct val *
  332. op_gt (a, b)
  333. struct val *a, *b;
  334. {
  335. struct val *r;
  336. if (isstring (a) || isstring (b)) {
  337. to_string (a);
  338. to_string (b);
  339. r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) > 0));
  340. } else {
  341. (void)to_integer(a);
  342. (void)to_integer(b);
  343. r = make_integer ((quad_t)(a->u.i > b->u.i));
  344. }
  345. free_value (a);
  346. free_value (b);
  347. return r;
  348. }
  349. static struct val *
  350. op_lt (a, b)
  351. struct val *a, *b;
  352. {
  353. struct val *r;
  354. if (isstring (a) || isstring (b)) {
  355. to_string (a);
  356. to_string (b);
  357. r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) < 0));
  358. } else {
  359. (void)to_integer(a);
  360. (void)to_integer(b);
  361. r = make_integer ((quad_t)(a->u.i < b->u.i));
  362. }
  363. free_value (a);
  364. free_value (b);
  365. return r;
  366. }
  367. static struct val *
  368. op_ge (a, b)
  369. struct val *a, *b;
  370. {
  371. struct val *r;
  372. if (isstring (a) || isstring (b)) {
  373. to_string (a);
  374. to_string (b);
  375. r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) >= 0));
  376. } else {
  377. (void)to_integer(a);
  378. (void)to_integer(b);
  379. r = make_integer ((quad_t)(a->u.i >= b->u.i));
  380. }
  381. free_value (a);
  382. free_value (b);
  383. return r;
  384. }
  385. static struct val *
  386. op_le (a, b)
  387. struct val *a, *b;
  388. {
  389. struct val *r;
  390. if (isstring (a) || isstring (b)) {
  391. to_string (a);
  392. to_string (b);
  393. r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) <= 0));
  394. } else {
  395. (void)to_integer(a);
  396. (void)to_integer(b);
  397. r = make_integer ((quad_t)(a->u.i <= b->u.i));
  398. }
  399. free_value (a);
  400. free_value (b);
  401. return r;
  402. }
  403. static struct val *
  404. op_ne (a, b)
  405. struct val *a, *b;
  406. {
  407. struct val *r;
  408. if (isstring (a) || isstring (b)) {
  409. to_string (a);
  410. to_string (b);
  411. r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) != 0));
  412. } else {
  413. (void)to_integer(a);
  414. (void)to_integer(b);
  415. r = make_integer ((quad_t)(a->u.i != b->u.i));
  416. }
  417. free_value (a);
  418. free_value (b);
  419. return r;
  420. }
  421. static int
  422. chk_plus (a, b, r)
  423. quad_t a, b, r;
  424. {
  425. /* sum of two positive numbers must be positive */
  426. if (a > 0 && b > 0 && r <= 0)
  427. return 1;
  428. /* sum of two negative numbers must be negative */
  429. if (a < 0 && b < 0 && r >= 0)
  430. return 1;
  431. /* all other cases are OK */
  432. return 0;
  433. }
  434. static struct val *
  435. op_plus (a, b)
  436. struct val *a, *b;
  437. {
  438. struct val *r;
  439. if (!to_integer (a) || !to_integer (b)) {
  440. ast_log(LOG_WARNING,"non-numeric argument\n");
  441. free_value(a);
  442. free_value(b);
  443. return(NULL);
  444. }
  445. r = make_integer (/*(quad_t)*/(a->u.i + b->u.i));
  446. if (chk_plus (a->u.i, b->u.i, r->u.i)) {
  447. ast_log(LOG_WARNING,"overflow\n");
  448. free_value(a);
  449. free_value(b);
  450. return(NULL);
  451. }
  452. free_value (a);
  453. free_value (b);
  454. return r;
  455. }
  456. static int
  457. chk_minus (a, b, r)
  458. quad_t a, b, r;
  459. {
  460. /* special case subtraction of QUAD_MIN */
  461. if (b == QUAD_MIN) {
  462. if (a >= 0)
  463. return 1;
  464. else
  465. return 0;
  466. }
  467. /* this is allowed for b != QUAD_MIN */
  468. return chk_plus (a, -b, r);
  469. }
  470. static struct val *
  471. op_minus (a, b)
  472. struct val *a, *b;
  473. {
  474. struct val *r;
  475. if (!to_integer (a) || !to_integer (b)) {
  476. free_value(a);
  477. free_value(b);
  478. ast_log(LOG_WARNING, "non-numeric argument\n");
  479. return(NULL);
  480. }
  481. r = make_integer (/*(quad_t)*/(a->u.i - b->u.i));
  482. if (chk_minus (a->u.i, b->u.i, r->u.i)) {
  483. free_value(a);
  484. free_value(b);
  485. ast_log(LOG_WARNING, "overload\n");
  486. return(NULL);
  487. }
  488. free_value (a);
  489. free_value (b);
  490. return r;
  491. }
  492. static int
  493. chk_times (a, b, r)
  494. quad_t a, b, r;
  495. {
  496. /* special case: first operand is 0, no overflow possible */
  497. if (a == 0)
  498. return 0;
  499. /* cerify that result of division matches second operand */
  500. if (r / a != b)
  501. return 1;
  502. return 0;
  503. }
  504. static struct val *
  505. op_times (a, b)
  506. struct val *a, *b;
  507. {
  508. struct val *r;
  509. if (!to_integer (a) || !to_integer (b)) {
  510. free_value(a);
  511. free_value(b);
  512. ast_log(LOG_WARNING, "non-numeric argument\n");
  513. return(NULL);
  514. }
  515. r = make_integer (/*(quad_t)*/(a->u.i * b->u.i));
  516. if (chk_times (a->u.i, b->u.i, r->u.i)) {
  517. ast_log(LOG_WARNING, "overflow\n");
  518. free_value(a);
  519. free_value(b);
  520. return(NULL);
  521. }
  522. free_value (a);
  523. free_value (b);
  524. return (r);
  525. }
  526. static int
  527. chk_div (a, b)
  528. quad_t a, b;
  529. {
  530. /* div by zero has been taken care of before */
  531. /* only QUAD_MIN / -1 causes overflow */
  532. if (a == QUAD_MIN && b == -1)
  533. return 1;
  534. /* everything else is OK */
  535. return 0;
  536. }
  537. static struct val *
  538. op_div (a, b)
  539. struct val *a, *b;
  540. {
  541. struct val *r;
  542. if (!to_integer (a) || !to_integer (b)) {
  543. free_value(a);
  544. free_value(b);
  545. ast_log(LOG_WARNING, "non-numeric argument\n");
  546. return(NULL);
  547. }
  548. if (b->u.i == 0) {
  549. ast_log(LOG_WARNING, "division by zero\n");
  550. free_value(a);
  551. free_value(b);
  552. return(NULL);
  553. }
  554. r = make_integer (/*(quad_t)*/(a->u.i / b->u.i));
  555. if (chk_div (a->u.i, b->u.i)) {
  556. ast_log(LOG_WARNING, "overflow\n");
  557. free_value(a);
  558. free_value(b);
  559. return(NULL);
  560. }
  561. free_value (a);
  562. free_value (b);
  563. return r;
  564. }
  565. static struct val *
  566. op_rem (a, b)
  567. struct val *a, *b;
  568. {
  569. struct val *r;
  570. if (!to_integer (a) || !to_integer (b)) {
  571. ast_log(LOG_WARNING, "non-numeric argument\n");
  572. free_value(a);
  573. free_value(b);
  574. return(NULL);
  575. }
  576. if (b->u.i == 0) {
  577. ast_log(LOG_WARNING, "div by zero\n");
  578. free_value(a);
  579. free_value(b);
  580. return(NULL);
  581. }
  582. r = make_integer (/*(quad_t)*/(a->u.i % b->u.i));
  583. /* chk_rem necessary ??? */
  584. free_value (a);
  585. free_value (b);
  586. return r;
  587. }
  588. static struct val *
  589. op_colon (a, b)
  590. struct val *a, *b;
  591. {
  592. regex_t rp;
  593. regmatch_t rm[2];
  594. char errbuf[256];
  595. int eval;
  596. struct val *v;
  597. /* coerce to both arguments to strings */
  598. to_string(a);
  599. to_string(b);
  600. /* compile regular expression */
  601. if ((eval = regcomp (&rp, b->u.s, 0)) != 0) {
  602. regerror (eval, &rp, errbuf, sizeof(errbuf));
  603. ast_log(LOG_WARNING,"regcomp() error : %s",errbuf);
  604. free_value(a);
  605. free_value(b);
  606. return(NULL);
  607. }
  608. /* compare string against pattern */
  609. /* remember that patterns are anchored to the beginning of the line */
  610. if (regexec(&rp, a->u.s, (size_t)2, rm, 0) == 0 && rm[0].rm_so == 0) {
  611. if (rm[1].rm_so >= 0) {
  612. *(a->u.s + rm[1].rm_eo) = '\0';
  613. v = make_str (a->u.s + rm[1].rm_so);
  614. } else {
  615. v = make_integer ((quad_t)(rm[0].rm_eo - rm[0].rm_so));
  616. }
  617. } else {
  618. if (rp.re_nsub == 0) {
  619. v = make_integer ((quad_t)0);
  620. } else {
  621. v = make_str ("");
  622. }
  623. }
  624. /* free arguments and pattern buffer */
  625. free_value (a);
  626. free_value (b);
  627. regfree (&rp);
  628. return v;
  629. }