ast_expr.y 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892
  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. #ifndef SOLARIS
  16. #include <err.h>
  17. #else
  18. #define quad_t uint64_t
  19. #endif
  20. #include <errno.h>
  21. #include <regex.h>
  22. #include <limits.h>
  23. #include "asterisk/ast_expr.h"
  24. #include "asterisk/logger.h"
  25. #ifndef QUAD_MIN
  26. #ifdef LONG_LONG_MIN
  27. #define QUAD_MIN LONG_LONG_MIN
  28. #else /* LONG_LONG_MIN */
  29. #define QUAD_MIN (-0x7fffffffffffffffL-1)
  30. #endif /* LONG_LONG_MIN */
  31. #endif /* QUAD_MIN */
  32. #ifndef QUAD_MAX
  33. #ifdef LONG_LONG_MAX
  34. #define QUAD_MAX LONG_LONG_MAX
  35. #else /* LONG_LONG_MAX */
  36. #define QUAD_MAX (0x7fffffffffffffffL)
  37. #endif /* LONG_LONG_MAX */
  38. #endif /* QUAD_MAX */
  39. #define YYPARSE_PARAM kota
  40. #define YYLEX_PARAM kota
  41. /* #define ast_log fprintf
  42. #define LOG_WARNING stderr */
  43. #ifdef SOLARIS
  44. #define __P(p) p
  45. #endif
  46. enum valtype {
  47. integer, numeric_string, string
  48. } ;
  49. struct val {
  50. enum valtype type;
  51. union {
  52. char *s;
  53. quad_t i;
  54. } u;
  55. } ;
  56. struct parser_control {
  57. struct val *result;
  58. int pipa;
  59. char *arg_orig;
  60. char *argv;
  61. char *ptrptr;
  62. int firsttoken;
  63. } ;
  64. static int chk_div __P((quad_t, quad_t));
  65. static int chk_minus __P((quad_t, quad_t, quad_t));
  66. static int chk_plus __P((quad_t, quad_t, quad_t));
  67. static int chk_times __P((quad_t, quad_t, quad_t));
  68. static void free_value __P((struct val *));
  69. static int is_zero_or_null __P((struct val *));
  70. static int isstring __P((struct val *));
  71. static struct val *make_integer __P((quad_t));
  72. static struct val *make_str __P((const char *));
  73. static struct val *op_and __P((struct val *, struct val *));
  74. static struct val *op_colon __P((struct val *, struct val *));
  75. static struct val *op_div __P((struct val *, struct val *));
  76. static struct val *op_eq __P((struct val *, struct val *));
  77. static struct val *op_ge __P((struct val *, struct val *));
  78. static struct val *op_gt __P((struct val *, struct val *));
  79. static struct val *op_le __P((struct val *, struct val *));
  80. static struct val *op_lt __P((struct val *, struct val *));
  81. static struct val *op_minus __P((struct val *, struct val *));
  82. static struct val *op_ne __P((struct val *, struct val *));
  83. static struct val *op_or __P((struct val *, struct val *));
  84. static struct val *op_plus __P((struct val *, struct val *));
  85. static struct val *op_rem __P((struct val *, struct val *));
  86. static struct val *op_times __P((struct val *, struct val *));
  87. static quad_t to_integer __P((struct val *));
  88. static void to_string __P((struct val *));
  89. /* uh, if I want to predeclare yylex with a YYLTYPE, I have to predeclare the yyltype... sigh */
  90. typedef struct yyltype
  91. {
  92. int first_line;
  93. int first_column;
  94. int last_line;
  95. int last_column;
  96. } yyltype;
  97. # define YYLTYPE yyltype
  98. # define YYLTYPE_IS_TRIVIAL 1
  99. static int ast_yyerror __P((const char *,YYLTYPE *, struct parser_control *));
  100. #define ast_yyerror(x) ast_yyerror(x,&yyloc,kota)
  101. %}
  102. %pure-parser
  103. %locations
  104. /* %debug for when you are having big problems */
  105. /* %name-prefix="ast_yy" */
  106. %union
  107. {
  108. struct val *val;
  109. }
  110. %{
  111. static int ast_yylex __P((YYSTYPE *, YYLTYPE *, struct parser_control *));
  112. %}
  113. %left <val> '|'
  114. %left <val> '&'
  115. %left <val> '=' '>' '<' GE LE NE
  116. %left <val> '+' '-'
  117. %left <val> '*' '/' '%'
  118. %left <val> ':'
  119. %token <val> TOKEN
  120. %type <val> start expr
  121. %%
  122. start: expr { ((struct parser_control *)kota)->result = $$; }
  123. ;
  124. expr: TOKEN
  125. | '(' expr ')' { $$ = $2; @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
  126. | expr '|' expr { $$ = op_or ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
  127. | expr '&' expr { $$ = op_and ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
  128. | expr '=' expr { $$ = op_eq ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
  129. | expr '>' expr { $$ = op_gt ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
  130. | expr '<' expr { $$ = op_lt ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
  131. | expr GE expr { $$ = op_ge ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
  132. | expr LE expr { $$ = op_le ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
  133. | expr NE expr { $$ = op_ne ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
  134. | expr '+' expr { $$ = op_plus ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
  135. | expr '-' expr { $$ = op_minus ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
  136. | expr '*' expr { $$ = op_times ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
  137. | expr '/' expr { $$ = op_div ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
  138. | expr '%' expr { $$ = op_rem ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
  139. | expr ':' expr { $$ = op_colon ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
  140. ;
  141. %%
  142. static struct val *
  143. make_integer (i)
  144. quad_t i;
  145. {
  146. struct val *vp;
  147. vp = (struct val *) malloc (sizeof (*vp));
  148. if (vp == NULL) {
  149. ast_log(LOG_WARNING, "malloc() failed\n");
  150. return(NULL);
  151. }
  152. vp->type = integer;
  153. vp->u.i = i;
  154. return vp;
  155. }
  156. static struct val *
  157. make_str (s)
  158. const char *s;
  159. {
  160. struct val *vp;
  161. size_t i;
  162. int isint;
  163. vp = (struct val *) malloc (sizeof (*vp));
  164. if (vp == NULL || ((vp->u.s = strdup (s)) == NULL)) {
  165. ast_log(LOG_WARNING,"malloc() failed\n");
  166. return(NULL);
  167. }
  168. for(i = 1, isint = isdigit(s[0]) || s[0] == '-';
  169. isint && i < strlen(s);
  170. i++)
  171. {
  172. if(!isdigit(s[i]))
  173. isint = 0;
  174. }
  175. if (isint)
  176. vp->type = numeric_string;
  177. else
  178. vp->type = string;
  179. return vp;
  180. }
  181. static void
  182. free_value (vp)
  183. struct val *vp;
  184. {
  185. if (vp==NULL) {
  186. return;
  187. }
  188. if (vp->type == string || vp->type == numeric_string)
  189. free (vp->u.s);
  190. free (vp);
  191. }
  192. static quad_t
  193. to_integer (vp)
  194. struct val *vp;
  195. {
  196. quad_t i;
  197. if (vp == NULL) {
  198. ast_log(LOG_WARNING,"vp==NULL in to_integer()\n");
  199. return(0);
  200. }
  201. if (vp->type == integer)
  202. return 1;
  203. if (vp->type == string)
  204. return 0;
  205. /* vp->type == numeric_string, make it numeric */
  206. errno = 0;
  207. i = strtoq(vp->u.s, (char**)NULL, 10);
  208. if (errno != 0) {
  209. free(vp->u.s);
  210. ast_log(LOG_WARNING,"overflow\n");
  211. return(0);
  212. }
  213. free (vp->u.s);
  214. vp->u.i = i;
  215. vp->type = integer;
  216. return 1;
  217. }
  218. static void
  219. to_string (vp)
  220. struct val *vp;
  221. {
  222. char *tmp;
  223. if (vp->type == string || vp->type == numeric_string)
  224. return;
  225. tmp = malloc ((size_t)25);
  226. if (tmp == NULL) {
  227. ast_log(LOG_WARNING,"malloc() failed\n");
  228. return;
  229. }
  230. sprintf (tmp, "%lld", (long long)vp->u.i);
  231. vp->type = string;
  232. vp->u.s = tmp;
  233. }
  234. static int
  235. isstring (vp)
  236. struct val *vp;
  237. {
  238. /* only TRUE if this string is not a valid integer */
  239. return (vp->type == string);
  240. }
  241. static int
  242. ast_yylex (YYSTYPE *lvalp, YYLTYPE *yylloc, struct parser_control *karoto)
  243. {
  244. char *p=0;
  245. char *t1=0;
  246. char savep = 0;
  247. char *savepp = 0;
  248. if (karoto->firsttoken==1) {
  249. t1 = karoto->argv;
  250. karoto->firsttoken = 0;
  251. } else {
  252. t1 = karoto->ptrptr;
  253. }
  254. while(*t1 && *t1 == ' ' ) /* we can remove worries about leading/multiple spaces being present */
  255. t1++;
  256. karoto->ptrptr = t1;
  257. yylloc->first_column = t1 - karoto->argv;
  258. while( *t1 && *t1 != ' ' && *t1 != '"') /* find the next space or quote */
  259. t1++;
  260. if( *t1 == ' ' )
  261. {
  262. *t1 = 0;
  263. p = karoto->ptrptr;
  264. karoto->ptrptr = t1+1;
  265. yylloc->last_column = t1 - karoto->argv;
  266. }
  267. else if (*t1 == '"' )
  268. {
  269. /* opening quote. find the closing quote */
  270. char *t2=t1+1;
  271. while( *t2 && *t2 != '"')
  272. t2++;
  273. if( *t2 == '"' )
  274. {
  275. if( *(t2+1) == ' ' || *(t2+1) == 0 )
  276. {
  277. if( *(t2+1) )
  278. {
  279. *(t2+1) = 0;
  280. karoto->ptrptr = t2+2;
  281. }
  282. else
  283. {
  284. karoto->ptrptr = t2+1;
  285. }
  286. }
  287. else
  288. {
  289. /* hmmm. what if another token is here? */
  290. /* maybe we can insert a space? */
  291. savep = *(t2+1);
  292. savepp = t2+1;
  293. *(t2+1) = 0;
  294. karoto->ptrptr = t2+1;
  295. }
  296. p = t1;
  297. }
  298. else
  299. {
  300. /* NOT GOOD -- no closing quote! */
  301. p = t1;
  302. karoto->ptrptr = t2;
  303. }
  304. yylloc->last_column = t2 - karoto->argv;
  305. }
  306. else if( *t1 == 0 )
  307. {
  308. if( t1 != karoto->ptrptr )
  309. {
  310. /* this is the last token */
  311. p = karoto->ptrptr;
  312. karoto->ptrptr = t1;
  313. }
  314. else
  315. {
  316. /* we are done. That was quick */
  317. p = karoto->ptrptr;
  318. yylloc->last_column = t1 - karoto->argv;
  319. }
  320. }
  321. if( *p == 0 )
  322. p = 0;
  323. if (p==NULL) {
  324. return (0);
  325. }
  326. if (strlen (p) == 1) {
  327. if (strchr ("|&=<>+-*/%:()", *p))
  328. return (*p);
  329. } else if (strlen (p) == 2 && p[1] == '=') {
  330. switch (*p) {
  331. case '>': return (GE);
  332. case '<': return (LE);
  333. case '!': return (NE);
  334. }
  335. }
  336. lvalp->val = make_str (p);
  337. if( savep )
  338. {
  339. *savepp = savep; /* restore the null terminated string */
  340. savepp = 0;
  341. savep = 0;
  342. }
  343. return (TOKEN);
  344. }
  345. static int
  346. is_zero_or_null (vp)
  347. struct val *vp;
  348. {
  349. if (vp->type == integer) {
  350. return (vp->u.i == 0);
  351. } else {
  352. return (*vp->u.s == 0 || (to_integer (vp) && vp->u.i == 0));
  353. }
  354. /* NOTREACHED */
  355. }
  356. char *ast_expr (char *arg)
  357. {
  358. struct parser_control karoto;
  359. char *kota;
  360. char *pirouni;
  361. kota=strdup(arg);
  362. karoto.result = NULL;
  363. karoto.firsttoken=1;
  364. karoto.argv=kota;
  365. karoto.arg_orig = arg;
  366. /* ast_yydebug = 1; */
  367. ast_yyparse ((void *)&karoto);
  368. free(kota);
  369. if (karoto.result==NULL) {
  370. pirouni=strdup("0");
  371. return(pirouni);
  372. } else {
  373. if (karoto.result->type == integer) {
  374. pirouni=malloc(256);
  375. sprintf (pirouni,"%lld", (long long)karoto.result->u.i);
  376. }
  377. else {
  378. pirouni=strdup(karoto.result->u.s);
  379. }
  380. free(karoto.result);
  381. }
  382. return(pirouni);
  383. }
  384. #ifdef STANDALONE
  385. int main(int argc,char **argv) {
  386. char *s;
  387. s=ast_expr(argv[1]);
  388. printf("=====%s======\n",s);
  389. }
  390. #endif
  391. #undef ast_yyerror
  392. #define ast_yyerror(x) ast_yyerror(x, YYLTYPE *yylloc, struct parser_control *karoto)
  393. static int
  394. ast_yyerror (const char *s)
  395. {
  396. char spacebuf[8000]; /* best safe than sorry */
  397. char spacebuf2[8000]; /* best safe than sorry */
  398. int i=0;
  399. spacebuf[0] = 0;
  400. if( yylloc->first_column > 7990 ) /* if things get out of whack, why crash? */
  401. yylloc->first_column = 7990;
  402. if( yylloc->last_column > 7990 )
  403. yylloc->last_column = 7990;
  404. for(i=0;i<yylloc->first_column;i++) spacebuf[i] = ' ';
  405. for( ;i<yylloc->last_column;i++) spacebuf[i] = '^';
  406. spacebuf[i] = 0;
  407. for(i=0;i<karoto->ptrptr-karoto->argv;i++) spacebuf2[i] = ' ';
  408. spacebuf2[i++]='^';
  409. spacebuf2[i]= 0;
  410. ast_log(LOG_WARNING,"ast_yyerror(): syntax error: %s; Input:\n%s\n%s\n%s\n",s,
  411. karoto->arg_orig,spacebuf,spacebuf2);
  412. return(0);
  413. }
  414. static struct val *
  415. op_or (a, b)
  416. struct val *a, *b;
  417. {
  418. if (is_zero_or_null (a)) {
  419. free_value (a);
  420. return (b);
  421. } else {
  422. free_value (b);
  423. return (a);
  424. }
  425. }
  426. static struct val *
  427. op_and (a, b)
  428. struct val *a, *b;
  429. {
  430. if (is_zero_or_null (a) || is_zero_or_null (b)) {
  431. free_value (a);
  432. free_value (b);
  433. return (make_integer ((quad_t)0));
  434. } else {
  435. free_value (b);
  436. return (a);
  437. }
  438. }
  439. static struct val *
  440. op_eq (a, b)
  441. struct val *a, *b;
  442. {
  443. struct val *r;
  444. if (isstring (a) || isstring (b)) {
  445. to_string (a);
  446. to_string (b);
  447. r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) == 0));
  448. } else {
  449. (void)to_integer(a);
  450. (void)to_integer(b);
  451. r = make_integer ((quad_t)(a->u.i == b->u.i));
  452. }
  453. free_value (a);
  454. free_value (b);
  455. return r;
  456. }
  457. static struct val *
  458. op_gt (a, b)
  459. struct val *a, *b;
  460. {
  461. struct val *r;
  462. if (isstring (a) || isstring (b)) {
  463. to_string (a);
  464. to_string (b);
  465. r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) > 0));
  466. } else {
  467. (void)to_integer(a);
  468. (void)to_integer(b);
  469. r = make_integer ((quad_t)(a->u.i > b->u.i));
  470. }
  471. free_value (a);
  472. free_value (b);
  473. return r;
  474. }
  475. static struct val *
  476. op_lt (a, b)
  477. struct val *a, *b;
  478. {
  479. struct val *r;
  480. if (isstring (a) || isstring (b)) {
  481. to_string (a);
  482. to_string (b);
  483. r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) < 0));
  484. } else {
  485. (void)to_integer(a);
  486. (void)to_integer(b);
  487. r = make_integer ((quad_t)(a->u.i < b->u.i));
  488. }
  489. free_value (a);
  490. free_value (b);
  491. return r;
  492. }
  493. static struct val *
  494. op_ge (a, b)
  495. struct val *a, *b;
  496. {
  497. struct val *r;
  498. if (isstring (a) || isstring (b)) {
  499. to_string (a);
  500. to_string (b);
  501. r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) >= 0));
  502. } else {
  503. (void)to_integer(a);
  504. (void)to_integer(b);
  505. r = make_integer ((quad_t)(a->u.i >= b->u.i));
  506. }
  507. free_value (a);
  508. free_value (b);
  509. return r;
  510. }
  511. static struct val *
  512. op_le (a, b)
  513. struct val *a, *b;
  514. {
  515. struct val *r;
  516. if (isstring (a) || isstring (b)) {
  517. to_string (a);
  518. to_string (b);
  519. r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) <= 0));
  520. } else {
  521. (void)to_integer(a);
  522. (void)to_integer(b);
  523. r = make_integer ((quad_t)(a->u.i <= b->u.i));
  524. }
  525. free_value (a);
  526. free_value (b);
  527. return r;
  528. }
  529. static struct val *
  530. op_ne (a, b)
  531. struct val *a, *b;
  532. {
  533. struct val *r;
  534. if (isstring (a) || isstring (b)) {
  535. to_string (a);
  536. to_string (b);
  537. r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) != 0));
  538. } else {
  539. (void)to_integer(a);
  540. (void)to_integer(b);
  541. r = make_integer ((quad_t)(a->u.i != b->u.i));
  542. }
  543. free_value (a);
  544. free_value (b);
  545. return r;
  546. }
  547. static int
  548. chk_plus (a, b, r)
  549. quad_t a, b, 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 (a, b)
  562. struct val *a, *b;
  563. {
  564. struct val *r;
  565. if (!to_integer (a)) {
  566. ast_log(LOG_WARNING,"non-numeric argument\n");
  567. if (!to_integer (b)) {
  568. free_value(a);
  569. free_value(b);
  570. return make_integer(0);
  571. } else {
  572. free_value(a);
  573. return (b);
  574. }
  575. } else if (!to_integer(b)) {
  576. free_value(b);
  577. return (a);
  578. }
  579. r = make_integer (/*(quad_t)*/(a->u.i + b->u.i));
  580. if (chk_plus (a->u.i, b->u.i, r->u.i)) {
  581. ast_log(LOG_WARNING,"overflow\n");
  582. }
  583. free_value (a);
  584. free_value (b);
  585. return r;
  586. }
  587. static int
  588. chk_minus (a, b, r)
  589. quad_t a, b, r;
  590. {
  591. /* special case subtraction of QUAD_MIN */
  592. if (b == QUAD_MIN) {
  593. if (a >= 0)
  594. return 1;
  595. else
  596. return 0;
  597. }
  598. /* this is allowed for b != QUAD_MIN */
  599. return chk_plus (a, -b, r);
  600. }
  601. static struct val *
  602. op_minus (a, b)
  603. struct val *a, *b;
  604. {
  605. struct val *r;
  606. if (!to_integer (a)) {
  607. ast_log(LOG_WARNING, "non-numeric argument\n");
  608. if (!to_integer (b)) {
  609. free_value(a);
  610. free_value(b);
  611. return make_integer(0);
  612. } else {
  613. r = make_integer(0 - b->u.i);
  614. free_value(a);
  615. free_value(b);
  616. return (r);
  617. }
  618. } else if (!to_integer(b)) {
  619. ast_log(LOG_WARNING, "non-numeric argument\n");
  620. free_value(b);
  621. return (a);
  622. }
  623. r = make_integer (/*(quad_t)*/(a->u.i - b->u.i));
  624. if (chk_minus (a->u.i, b->u.i, r->u.i)) {
  625. ast_log(LOG_WARNING, "overflow\n");
  626. }
  627. free_value (a);
  628. free_value (b);
  629. return r;
  630. }
  631. static int
  632. chk_times (a, b, r)
  633. quad_t a, b, r;
  634. {
  635. /* special case: first operand is 0, no overflow possible */
  636. if (a == 0)
  637. return 0;
  638. /* cerify that result of division matches second operand */
  639. if (r / a != b)
  640. return 1;
  641. return 0;
  642. }
  643. static struct val *
  644. op_times (a, b)
  645. struct val *a, *b;
  646. {
  647. struct val *r;
  648. if (!to_integer (a) || !to_integer (b)) {
  649. free_value(a);
  650. free_value(b);
  651. ast_log(LOG_WARNING, "non-numeric argument\n");
  652. return(make_integer(0));
  653. }
  654. r = make_integer (/*(quad_t)*/(a->u.i * b->u.i));
  655. if (chk_times (a->u.i, b->u.i, r->u.i)) {
  656. ast_log(LOG_WARNING, "overflow\n");
  657. }
  658. free_value (a);
  659. free_value (b);
  660. return (r);
  661. }
  662. static int
  663. chk_div (a, b)
  664. quad_t a, b;
  665. {
  666. /* div by zero has been taken care of before */
  667. /* only QUAD_MIN / -1 causes overflow */
  668. if (a == QUAD_MIN && b == -1)
  669. return 1;
  670. /* everything else is OK */
  671. return 0;
  672. }
  673. static struct val *
  674. op_div (a, b)
  675. struct val *a, *b;
  676. {
  677. struct val *r;
  678. if (!to_integer (a)) {
  679. free_value(a);
  680. free_value(b);
  681. ast_log(LOG_WARNING, "non-numeric argument\n");
  682. return make_integer(0);
  683. } else if (!to_integer (b)) {
  684. free_value(a);
  685. free_value(b);
  686. ast_log(LOG_WARNING, "non-numeric argument\n");
  687. return make_integer(INT_MAX);
  688. }
  689. if (b->u.i == 0) {
  690. ast_log(LOG_WARNING, "division by zero\n");
  691. free_value(a);
  692. free_value(b);
  693. return make_integer(INT_MAX);
  694. }
  695. r = make_integer (/*(quad_t)*/(a->u.i / b->u.i));
  696. if (chk_div (a->u.i, b->u.i)) {
  697. ast_log(LOG_WARNING, "overflow\n");
  698. }
  699. free_value (a);
  700. free_value (b);
  701. return r;
  702. }
  703. static struct val *
  704. op_rem (a, b)
  705. struct val *a, *b;
  706. {
  707. struct val *r;
  708. if (!to_integer (a) || !to_integer (b)) {
  709. ast_log(LOG_WARNING, "non-numeric argument\n");
  710. free_value(a);
  711. free_value(b);
  712. return make_integer(0);
  713. }
  714. if (b->u.i == 0) {
  715. ast_log(LOG_WARNING, "div by zero\n");
  716. free_value(a);
  717. return (b);
  718. }
  719. r = make_integer (/*(quad_t)*/(a->u.i % b->u.i));
  720. /* chk_rem necessary ??? */
  721. free_value (a);
  722. free_value (b);
  723. return r;
  724. }
  725. static struct val *
  726. op_colon (a, b)
  727. struct val *a, *b;
  728. {
  729. regex_t rp;
  730. regmatch_t rm[2];
  731. char errbuf[256];
  732. int eval;
  733. struct val *v;
  734. /* coerce to both arguments to strings */
  735. to_string(a);
  736. to_string(b);
  737. /* compile regular expression */
  738. if ((eval = regcomp (&rp, b->u.s, REG_EXTENDED)) != 0) {
  739. regerror (eval, &rp, errbuf, sizeof(errbuf));
  740. ast_log(LOG_WARNING,"regcomp() error : %s",errbuf);
  741. free_value(a);
  742. free_value(b);
  743. return make_str("");
  744. }
  745. /* compare string against pattern */
  746. /* remember that patterns are anchored to the beginning of the line */
  747. if (regexec(&rp, a->u.s, (size_t)2, rm, 0) == 0 && rm[0].rm_so == 0) {
  748. if (rm[1].rm_so >= 0) {
  749. *(a->u.s + rm[1].rm_eo) = '\0';
  750. v = make_str (a->u.s + rm[1].rm_so);
  751. } else {
  752. v = make_integer ((quad_t)(rm[0].rm_eo - rm[0].rm_so));
  753. }
  754. } else {
  755. if (rp.re_nsub == 0) {
  756. v = make_integer ((quad_t)0);
  757. } else {
  758. v = make_str ("");
  759. }
  760. }
  761. /* free arguments and pattern buffer */
  762. free_value (a);
  763. free_value (b);
  764. regfree (&rp);
  765. return v;
  766. }