PageRenderTime 59ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/src/rec-sex.c

#
C | 1172 lines | 939 code | 159 blank | 74 comment | 122 complexity | d511d52582bdd85635ac49c60acc61da MD5 | raw file
Possible License(s): GPL-3.0
  1. /* -*- mode: C -*-
  2. *
  3. * File: rec-sex.c
  4. * Date: Sat Jan 9 20:28:43 2010
  5. *
  6. * GNU recutils - Record Selection Expressions.
  7. *
  8. */
  9. /* Copyright (C) 2010-2013 Jose E. Marchesi */
  10. /* This program is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation, either version 3 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. */
  23. #include <config.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <regex.h>
  27. #include <parse-datetime.h>
  28. #include <rec.h>
  29. #include <rec-utils.h>
  30. #include <rec-sex-ast.h>
  31. #include <rec-sex-parser.h>
  32. #include <rec-sex-tab.h>
  33. /*
  34. * Data structures
  35. */
  36. struct rec_sex_s
  37. {
  38. rec_sex_ast_t ast;
  39. rec_sex_parser_t parser;
  40. };
  41. #define REC_SEX_VAL_INT 0
  42. #define REC_SEX_VAL_REAL 1
  43. #define REC_SEX_VAL_STR 2
  44. struct rec_sex_val_s
  45. {
  46. int type;
  47. int int_val;
  48. double real_val;
  49. char *str_val;
  50. };
  51. /* Static functions declarations. */
  52. static struct rec_sex_val_s rec_sex_eval_node (rec_sex_t sex,
  53. rec_record_t record,
  54. rec_sex_ast_node_t node,
  55. bool *status);
  56. static bool rec_sex_op_real_p (struct rec_sex_val_s op1,
  57. struct rec_sex_val_s op2);
  58. /*
  59. * Public functions.
  60. */
  61. rec_sex_t
  62. rec_sex_new (bool case_insensitive)
  63. {
  64. rec_sex_t new;
  65. new = malloc (sizeof (struct rec_sex_s));
  66. if (new)
  67. {
  68. /* Initialize a new parser. */
  69. new->parser = rec_sex_parser_new ();
  70. rec_sex_parser_set_case_insensitive (new->parser,
  71. case_insensitive);
  72. /* Initialize a new AST. */
  73. new->ast = NULL;
  74. }
  75. return new;
  76. }
  77. void
  78. rec_sex_destroy (rec_sex_t sex)
  79. {
  80. if (sex)
  81. {
  82. if (sex->parser)
  83. {
  84. rec_sex_parser_destroy (sex->parser);
  85. }
  86. if (sex->ast)
  87. {
  88. rec_sex_ast_destroy (sex->ast);
  89. }
  90. free (sex); /* yeah! :D */
  91. }
  92. }
  93. bool
  94. rec_sex_compile (rec_sex_t sex,
  95. const char *expr)
  96. {
  97. bool res;
  98. res = rec_sex_parser_run (sex->parser, expr);
  99. if (res)
  100. {
  101. sex->ast = rec_sex_parser_ast (sex->parser);
  102. }
  103. return res;
  104. }
  105. #define EXEC_AST(RECORD) \
  106. do \
  107. { \
  108. val = rec_sex_eval_node (sex, \
  109. (RECORD), \
  110. rec_sex_ast_top (sex->ast), \
  111. status); \
  112. \
  113. switch (val.type) \
  114. { \
  115. case REC_SEX_VAL_INT: \
  116. { \
  117. res = (val.int_val != 0); \
  118. break; \
  119. } \
  120. case REC_SEX_VAL_REAL: \
  121. case REC_SEX_VAL_STR: \
  122. { \
  123. res = false; \
  124. break; \
  125. } \
  126. } \
  127. } \
  128. while (0)
  129. char *
  130. rec_sex_eval_str (rec_sex_t sex,
  131. rec_record_t record)
  132. {
  133. char *res;
  134. struct rec_sex_val_s val;
  135. bool status;
  136. rec_sex_ast_node_unfix (rec_sex_ast_top (sex->ast));
  137. val = rec_sex_eval_node (sex,
  138. record,
  139. rec_sex_ast_top (sex->ast),
  140. &status);
  141. if (!status)
  142. {
  143. /* Error evaluating the expression. */
  144. return NULL;
  145. }
  146. res = NULL;
  147. switch (val.type)
  148. {
  149. case REC_SEX_VAL_INT:
  150. {
  151. asprintf (&res, "%d", val.int_val);
  152. break;
  153. }
  154. case REC_SEX_VAL_REAL:
  155. {
  156. asprintf (&res, "%f", val.real_val);
  157. break;
  158. }
  159. case REC_SEX_VAL_STR:
  160. {
  161. res = strdup (val.str_val);
  162. break;
  163. }
  164. }
  165. return res;
  166. }
  167. bool
  168. rec_sex_eval (rec_sex_t sex,
  169. rec_record_t record,
  170. bool *status)
  171. {
  172. bool res;
  173. rec_field_t field;
  174. rec_field_t wfield;
  175. rec_record_t wrec;
  176. rec_mset_iterator_t iter;
  177. int j, nf;
  178. struct rec_sex_val_s val;
  179. res = false;
  180. wrec = NULL;
  181. rec_sex_ast_node_unfix (rec_sex_ast_top (sex->ast));
  182. EXEC_AST (record);
  183. if (res)
  184. {
  185. goto exit;
  186. }
  187. rec_record_reset_marks (record);
  188. iter = rec_mset_iterator (rec_record_mset (record));
  189. while (rec_mset_iterator_next (&iter, MSET_FIELD, (const void**) &field, NULL))
  190. {
  191. nf = rec_record_get_num_fields_by_name (record, rec_field_name (field));
  192. if ((nf > 1)
  193. && (rec_record_field_mark (record, field) == 0)
  194. && (rec_sex_ast_name_p (sex->ast, rec_field_name (field), nf))
  195. && (!rec_sex_ast_hash_name_p (sex->ast, rec_field_name (field))))
  196. {
  197. for (j = 0; j < nf; j++)
  198. {
  199. wfield = rec_record_get_field_by_name (record,
  200. rec_field_name (field),
  201. j);
  202. if (wrec)
  203. {
  204. rec_record_destroy (wrec);
  205. }
  206. rec_record_mark_field (record, wfield, 1);
  207. wrec = rec_record_dup (record);
  208. rec_record_remove_field_by_name (wrec,
  209. rec_field_name (field),
  210. -1); /* Delete all. */
  211. rec_mset_append (rec_record_mset (wrec), MSET_FIELD, (void *) rec_field_dup (wfield), MSET_ANY);
  212. EXEC_AST(wrec);
  213. if (res)
  214. {
  215. rec_record_destroy (wrec);
  216. goto exit;
  217. }
  218. }
  219. }
  220. }
  221. rec_mset_iterator_free (&iter);
  222. exit:
  223. if (!*status)
  224. {
  225. res = false;
  226. }
  227. return res;
  228. }
  229. void
  230. rec_sex_print_ast (rec_sex_t sex)
  231. {
  232. rec_sex_parser_print_ast (sex->parser);
  233. }
  234. /*
  235. * Private functions.
  236. */
  237. #define GET_CHILD_VAL(DEST,NUM) \
  238. do \
  239. { \
  240. (DEST) = rec_sex_eval_node (sex, \
  241. record, \
  242. rec_sex_ast_node_child (node, (NUM)), \
  243. status); \
  244. if (!*status) \
  245. { \
  246. return res; \
  247. } \
  248. } \
  249. while (0)
  250. #define ATOI_VAL(DEST, VAL) \
  251. do \
  252. { \
  253. switch ((VAL).type) \
  254. { \
  255. case REC_SEX_VAL_INT: \
  256. { \
  257. (DEST) = (VAL).int_val; \
  258. break; \
  259. } \
  260. case REC_SEX_VAL_STR: \
  261. { \
  262. if (strcmp ((VAL).str_val, "") == 0) \
  263. { \
  264. (DEST) = 0; \
  265. } \
  266. else \
  267. { \
  268. if (!rec_atoi ((VAL).str_val, &(DEST))) \
  269. { \
  270. *status = false; \
  271. return res; \
  272. } \
  273. } \
  274. break; \
  275. } \
  276. } \
  277. } \
  278. while (0)
  279. #define ATOD_VAL(DEST, VAL) \
  280. do \
  281. { \
  282. switch ((VAL).type) \
  283. { \
  284. case REC_SEX_VAL_REAL: \
  285. { \
  286. (DEST) = (VAL).real_val; \
  287. break; \
  288. } \
  289. case REC_SEX_VAL_INT: \
  290. { \
  291. (DEST) = (VAL).int_val; \
  292. break; \
  293. } \
  294. case REC_SEX_VAL_STR: \
  295. { \
  296. if (strcmp ((VAL).str_val, "") == 0) \
  297. { \
  298. (DEST) = 0.0; \
  299. } \
  300. else \
  301. { \
  302. if (!rec_atod ((VAL).str_val, &(DEST))) \
  303. { \
  304. *status = false; \
  305. return res; \
  306. } \
  307. } \
  308. break; \
  309. } \
  310. } \
  311. } \
  312. while (0)
  313. #define ATOTS_VAL(DEST, VAL) \
  314. do \
  315. { \
  316. switch ((VAL).type) \
  317. { \
  318. case REC_SEX_VAL_REAL: \
  319. { \
  320. *status = false; \
  321. return res; \
  322. break; \
  323. } \
  324. case REC_SEX_VAL_INT: \
  325. { \
  326. *status = false; \
  327. return res; \
  328. break; \
  329. } \
  330. case REC_SEX_VAL_STR: \
  331. { \
  332. if (!parse_datetime (&(DEST), (VAL).str_val, NULL))\
  333. { \
  334. *status = false; \
  335. return res; \
  336. } \
  337. \
  338. break; \
  339. } \
  340. } \
  341. } \
  342. while (0)
  343. struct rec_sex_val_s
  344. rec_sex_eval_node (rec_sex_t sex,
  345. rec_record_t record,
  346. rec_sex_ast_node_t node,
  347. bool *status)
  348. {
  349. struct rec_sex_val_s res = {0, 0, 0, NULL};
  350. struct rec_sex_val_s child_val1 = {0, 0, 0, NULL};
  351. struct rec_sex_val_s child_val2 = {0, 0, 0, NULL};
  352. struct rec_sex_val_s child_val3 = {0, 0, 0, NULL};
  353. *status = true;
  354. switch (rec_sex_ast_node_type (node))
  355. {
  356. case REC_SEX_NOVAL:
  357. {
  358. fprintf (stderr, "Application bug: REC_SEX_NOVAL node found.\nPlease report this!\n");
  359. exit (EXIT_FAILURE);
  360. break;
  361. }
  362. /* Operations. */
  363. case REC_SEX_OP_NEG:
  364. case REC_SEX_OP_ADD:
  365. {
  366. int op1;
  367. int op2;
  368. double op1_real;
  369. double op2_real;
  370. GET_CHILD_VAL (child_val1, 0);
  371. GET_CHILD_VAL (child_val2, 1);
  372. if (rec_sex_op_real_p (child_val1, child_val2))
  373. {
  374. /* Real operation. */
  375. ATOD_VAL (op1_real, child_val1);
  376. ATOD_VAL (op2_real, child_val2);
  377. res.type = REC_SEX_VAL_REAL;
  378. res.real_val = op1_real + op2_real;
  379. }
  380. else
  381. {
  382. /* Integer operation. */
  383. ATOI_VAL (op1, child_val1);
  384. ATOI_VAL (op2, child_val2);
  385. res.type = REC_SEX_VAL_INT;
  386. res.int_val = op1 + op2;
  387. }
  388. break;
  389. }
  390. case REC_SEX_OP_SUB:
  391. {
  392. int op1;
  393. int op2;
  394. double op1_real;
  395. double op2_real;
  396. GET_CHILD_VAL (child_val1, 0);
  397. GET_CHILD_VAL (child_val2, 1);
  398. if (rec_sex_op_real_p (child_val1, child_val2))
  399. {
  400. /* Real operation. */
  401. ATOD_VAL (op1_real, child_val1);
  402. ATOD_VAL (op2_real, child_val2);
  403. res.type = REC_SEX_VAL_REAL;
  404. res.real_val = op1 - op2;
  405. }
  406. else
  407. {
  408. /* Integer operation. */
  409. ATOI_VAL (op1, child_val1);
  410. ATOI_VAL (op2, child_val2);
  411. res.type = REC_SEX_VAL_INT;
  412. res.int_val = op1 - op2;
  413. }
  414. break;
  415. }
  416. case REC_SEX_OP_MUL:
  417. {
  418. int op1;
  419. int op2;
  420. double op1_real;
  421. double op2_real;
  422. GET_CHILD_VAL (child_val1, 0);
  423. GET_CHILD_VAL (child_val2, 1);
  424. if (rec_sex_op_real_p (child_val1, child_val2))
  425. {
  426. /* Real operation. */
  427. ATOD_VAL (op1_real, child_val1);
  428. ATOD_VAL (op2_real, child_val2);
  429. res.type = REC_SEX_VAL_REAL;
  430. res.real_val = op1_real * op2_real;
  431. }
  432. else
  433. {
  434. /* Integer operation. */
  435. ATOI_VAL (op1, child_val1);
  436. ATOI_VAL (op2, child_val2);
  437. res.type = REC_SEX_VAL_INT;
  438. res.int_val = op1 * op2;
  439. }
  440. break;
  441. }
  442. case REC_SEX_OP_DIV:
  443. {
  444. int op1;
  445. int op2;
  446. double op1_real;
  447. double op2_real;
  448. GET_CHILD_VAL (child_val1, 0);
  449. GET_CHILD_VAL (child_val2, 1);
  450. if (rec_sex_op_real_p (child_val1, child_val2))
  451. {
  452. /* Real operation. */
  453. ATOD_VAL (op1_real, child_val1);
  454. ATOD_VAL (op2_real, child_val2);
  455. res.type = REC_SEX_VAL_REAL;
  456. res.real_val = op1_real / op2_real;
  457. }
  458. else
  459. {
  460. /* Integer operation. */
  461. ATOI_VAL (op1, child_val1);
  462. ATOI_VAL (op2, child_val2);
  463. res.type = REC_SEX_VAL_INT;
  464. if (op2 != 0)
  465. {
  466. res.int_val = op1 / op2;
  467. }
  468. else
  469. {
  470. /* Error: division by zero */
  471. *status = false;
  472. return res;
  473. }
  474. }
  475. break;
  476. }
  477. case REC_SEX_OP_MOD:
  478. {
  479. int op1;
  480. int op2;
  481. GET_CHILD_VAL (child_val1, 0);
  482. GET_CHILD_VAL (child_val2, 1);
  483. /* Integer operation. */
  484. ATOI_VAL (op1, child_val1);
  485. ATOI_VAL (op2, child_val2);
  486. res.type = REC_SEX_VAL_INT;
  487. if (op2 != 0)
  488. {
  489. res.int_val = op1 % op2;
  490. }
  491. else
  492. {
  493. /* Error: division by zero */
  494. *status = false;
  495. return res;
  496. }
  497. break;
  498. }
  499. case REC_SEX_OP_EQL:
  500. {
  501. int op1;
  502. int op2;
  503. double op1_real;
  504. double op2_real;
  505. GET_CHILD_VAL (child_val1, 0);
  506. GET_CHILD_VAL (child_val2, 1);
  507. if ((child_val1.type == REC_SEX_VAL_STR)
  508. && (child_val2.type == REC_SEX_VAL_STR))
  509. {
  510. /* String comparison. */
  511. res.type = REC_SEX_VAL_INT;
  512. if (rec_sex_parser_case_insensitive (sex->parser))
  513. {
  514. res.int_val = (strcasecmp (child_val1.str_val,
  515. child_val2.str_val) == 0);
  516. }
  517. else
  518. {
  519. res.int_val = (strcmp (child_val1.str_val,
  520. child_val2.str_val) == 0);
  521. }
  522. }
  523. else
  524. {
  525. if (rec_sex_op_real_p (child_val1, child_val2))
  526. {
  527. /* Real comparison. */
  528. ATOD_VAL (op1_real, child_val1);
  529. ATOD_VAL (op2_real, child_val2);
  530. res.type = REC_SEX_VAL_INT;
  531. res.int_val = op1_real == op2_real;
  532. }
  533. else
  534. {
  535. /* Integer comparison. */
  536. ATOI_VAL (op1, child_val1);
  537. ATOI_VAL (op2, child_val2);
  538. res.type = REC_SEX_VAL_INT;
  539. res.int_val = op1 == op2;
  540. }
  541. }
  542. break;
  543. }
  544. case REC_SEX_OP_NEQ:
  545. {
  546. int op1;
  547. int op2;
  548. double op1_real;
  549. double op2_real;
  550. GET_CHILD_VAL (child_val1, 0);
  551. GET_CHILD_VAL (child_val2, 1);
  552. if ((child_val1.type == REC_SEX_VAL_STR)
  553. && (child_val2.type == REC_SEX_VAL_STR))
  554. {
  555. /* String comparison. */
  556. res.type = REC_SEX_VAL_INT;
  557. if (rec_sex_parser_case_insensitive (sex->parser))
  558. {
  559. res.int_val = (strcasecmp (child_val1.str_val,
  560. child_val2.str_val) != 0);
  561. }
  562. else
  563. {
  564. res.int_val = (strcmp (child_val1.str_val,
  565. child_val2.str_val) != 0);
  566. }
  567. }
  568. else
  569. {
  570. if (rec_sex_op_real_p (child_val1, child_val2))
  571. {
  572. /* Real comparison. */
  573. ATOD_VAL (op1_real, child_val1);
  574. ATOD_VAL (op2_real, child_val2);
  575. res.type = REC_SEX_VAL_INT;
  576. res.int_val = op1_real != op2_real;
  577. }
  578. else
  579. {
  580. /* Integer comparison. */
  581. ATOI_VAL (op1, child_val1);
  582. ATOI_VAL (op2, child_val2);
  583. res.type = REC_SEX_VAL_INT;
  584. res.int_val = op1 != op2;
  585. }
  586. }
  587. break;
  588. }
  589. case REC_SEX_OP_MAT:
  590. {
  591. GET_CHILD_VAL (child_val1, 0);
  592. GET_CHILD_VAL (child_val2, 1);
  593. if ((child_val1.type == REC_SEX_VAL_STR)
  594. && (child_val2.type == REC_SEX_VAL_STR))
  595. {
  596. /* String match. */
  597. res.type = REC_SEX_VAL_INT;
  598. if (rec_sex_parser_case_insensitive (sex->parser))
  599. {
  600. res.int_val =
  601. rec_match_insensitive (child_val1.str_val, child_val2.str_val);
  602. }
  603. else
  604. {
  605. res.int_val =
  606. rec_match (child_val1.str_val, child_val2.str_val);
  607. }
  608. }
  609. else
  610. {
  611. /* Error. */
  612. *status = false;
  613. return res;
  614. }
  615. break;
  616. }
  617. case REC_SEX_OP_BEFORE:
  618. {
  619. struct timespec op1;
  620. struct timespec op2;
  621. struct timespec diff;
  622. GET_CHILD_VAL (child_val1, 0);
  623. GET_CHILD_VAL (child_val2, 1);
  624. ATOTS_VAL (op1, child_val1);
  625. ATOTS_VAL (op2, child_val2);
  626. res.type = REC_SEX_VAL_INT;
  627. res.int_val = rec_timespec_subtract (&diff, &op1, &op2);
  628. break;
  629. }
  630. case REC_SEX_OP_AFTER:
  631. {
  632. struct timespec op1;
  633. struct timespec op2;
  634. struct timespec diff;
  635. GET_CHILD_VAL (child_val1, 0);
  636. GET_CHILD_VAL (child_val2, 1);
  637. ATOTS_VAL (op1, child_val1);
  638. ATOTS_VAL (op2, child_val2);
  639. res.type = REC_SEX_VAL_INT;
  640. res.int_val = (!rec_timespec_subtract (&diff, &op1, &op2)
  641. && ((diff.tv_sec != 0) || (diff.tv_nsec != 0)));
  642. break;
  643. }
  644. case REC_SEX_OP_SAMETIME:
  645. {
  646. struct timespec op1;
  647. struct timespec op2;
  648. struct timespec diff;
  649. GET_CHILD_VAL (child_val1, 0);
  650. GET_CHILD_VAL (child_val2, 1);
  651. ATOTS_VAL (op1, child_val1);
  652. ATOTS_VAL (op2, child_val2);
  653. rec_timespec_subtract (&diff, &op1, &op2);
  654. res.type = REC_SEX_VAL_INT;
  655. res.int_val = ((diff.tv_sec == 0) && (diff.tv_nsec == 0));
  656. break;
  657. }
  658. case REC_SEX_OP_IMPLIES:
  659. {
  660. int op1;
  661. int op2;
  662. GET_CHILD_VAL (child_val1, 0);
  663. GET_CHILD_VAL (child_val2, 1);
  664. ATOI_VAL (op1, child_val1);
  665. ATOI_VAL (op2, child_val2);
  666. res.type = REC_SEX_VAL_INT;
  667. res.int_val = !op1 || (op1 && op2);
  668. break;
  669. }
  670. case REC_SEX_OP_LT:
  671. case REC_SEX_OP_LTE:
  672. {
  673. int op1;
  674. int op2;
  675. double op1_real;
  676. double op2_real;
  677. GET_CHILD_VAL (child_val1, 0);
  678. GET_CHILD_VAL (child_val2, 1);
  679. if (rec_sex_op_real_p (child_val1, child_val2))
  680. {
  681. /* Real comparison. */
  682. ATOD_VAL (op1_real, child_val1);
  683. ATOD_VAL (op2_real, child_val2);
  684. res.type = REC_SEX_VAL_INT;
  685. if (rec_sex_ast_node_type (node) == REC_SEX_OP_LT)
  686. {
  687. res.int_val = op1_real < op2_real;
  688. }
  689. else
  690. {
  691. res.int_val = op1_real <= op2_real;
  692. }
  693. }
  694. else
  695. {
  696. /* Integer comparison. */
  697. ATOI_VAL (op1, child_val1);
  698. ATOI_VAL (op2, child_val2);
  699. res.type = REC_SEX_VAL_INT;
  700. if (rec_sex_ast_node_type (node) == REC_SEX_OP_LT)
  701. {
  702. res.int_val = op1 < op2;
  703. }
  704. else
  705. {
  706. res.int_val = op1 <= op2;
  707. }
  708. }
  709. break;
  710. }
  711. case REC_SEX_OP_GT:
  712. case REC_SEX_OP_GTE:
  713. {
  714. int op1;
  715. int op2;
  716. double op1_real;
  717. double op2_real;
  718. GET_CHILD_VAL (child_val1, 0);
  719. GET_CHILD_VAL (child_val2, 1);
  720. if (rec_sex_op_real_p (child_val1, child_val2))
  721. {
  722. /* Real comparison. */
  723. ATOD_VAL (op1_real, child_val1);
  724. ATOD_VAL (op2_real, child_val2);
  725. res.type = REC_SEX_VAL_INT;
  726. if (rec_sex_ast_node_type (node) == REC_SEX_OP_GT)
  727. {
  728. res.int_val = op1_real > op2_real;
  729. }
  730. else
  731. {
  732. res.int_val = op1_real >= op2_real;
  733. }
  734. }
  735. else
  736. {
  737. /* Integer comparison. */
  738. ATOI_VAL (op1, child_val1);
  739. ATOI_VAL (op2, child_val2);
  740. res.type = REC_SEX_VAL_INT;
  741. if (rec_sex_ast_node_type (node) == REC_SEX_OP_GT)
  742. {
  743. res.int_val = op1 > op2;
  744. }
  745. else
  746. {
  747. res.int_val = op1 >= op2;
  748. }
  749. }
  750. break;
  751. }
  752. case REC_SEX_OP_AND:
  753. {
  754. int op1;
  755. int op2;
  756. GET_CHILD_VAL (child_val1, 0);
  757. GET_CHILD_VAL (child_val2, 1);
  758. ATOI_VAL (op1, child_val1);
  759. ATOI_VAL (op2, child_val2);
  760. res.type = REC_SEX_VAL_INT;
  761. res.int_val = op1 && op2;
  762. break;
  763. }
  764. case REC_SEX_OP_OR:
  765. {
  766. int op1;
  767. int op2;
  768. GET_CHILD_VAL (child_val1, 0);
  769. GET_CHILD_VAL (child_val2, 1);
  770. ATOI_VAL (op1, child_val1);
  771. ATOI_VAL (op2, child_val2);
  772. res.type = REC_SEX_VAL_INT;
  773. res.int_val = op1 || op2;
  774. break;
  775. }
  776. case REC_SEX_OP_CONCAT:
  777. {
  778. size_t str1_size;
  779. size_t str2_size;
  780. GET_CHILD_VAL (child_val1, 0);
  781. GET_CHILD_VAL (child_val2, 1);
  782. if ((child_val1.type == REC_SEX_VAL_STR)
  783. && (child_val2.type == REC_SEX_VAL_STR))
  784. {
  785. str1_size = strlen (child_val1.str_val);
  786. str2_size = strlen (child_val2.str_val);
  787. res.type = REC_SEX_VAL_STR;
  788. res.str_val = malloc (str1_size + str2_size + 1);
  789. memcpy (res.str_val, child_val1.str_val, str1_size);
  790. memcpy (res.str_val + str1_size, child_val2.str_val, str2_size);
  791. res.str_val[str1_size + str2_size] = '\0';
  792. }
  793. else
  794. {
  795. *status = false;
  796. return res;
  797. }
  798. break;
  799. }
  800. case REC_SEX_OP_NOT:
  801. {
  802. int op;
  803. GET_CHILD_VAL (child_val1, 0);
  804. ATOI_VAL (op, child_val1);
  805. res.type = REC_SEX_VAL_INT;
  806. res.int_val = !op;
  807. break;
  808. }
  809. case REC_SEX_OP_SHA:
  810. {
  811. int n;
  812. const char *field_name = NULL;
  813. const char *field_subname = NULL;
  814. rec_sex_ast_node_t child;
  815. /* The child should be a Name. */
  816. child = rec_sex_ast_node_child (node, 0);
  817. if (rec_sex_ast_node_type (rec_sex_ast_node_child(node, 0))
  818. != REC_SEX_NAME)
  819. {
  820. *status = false;
  821. return res;
  822. }
  823. field_name = rec_sex_ast_node_name (child);
  824. field_subname = rec_sex_ast_node_subname (child);
  825. if (field_subname)
  826. {
  827. /* Compound a field name from the name/subname pair in the
  828. AST node. */
  829. char *effective_name
  830. = rec_concat_strings (field_name, "_", field_subname);
  831. n = rec_record_get_num_fields_by_name (record,
  832. effective_name);
  833. free (effective_name);
  834. }
  835. else
  836. {
  837. n = rec_record_get_num_fields_by_name (record, field_name);
  838. }
  839. res.type = REC_SEX_VAL_INT;
  840. res.int_val = n;
  841. break;
  842. }
  843. case REC_SEX_OP_COND:
  844. {
  845. int op1;
  846. GET_CHILD_VAL (child_val1, 0);
  847. GET_CHILD_VAL (child_val2, 1);
  848. GET_CHILD_VAL (child_val3, 2);
  849. /* Get the boolean value of the first operand. */
  850. ATOI_VAL (op1, child_val1);
  851. /* Return the first or the second operand, depending on the
  852. value of op1. */
  853. if (op1)
  854. {
  855. res = child_val2;
  856. }
  857. else
  858. {
  859. res = child_val3;
  860. }
  861. break;
  862. }
  863. /* Values. */
  864. case REC_SEX_INT:
  865. {
  866. res.type = REC_SEX_VAL_INT;
  867. res.int_val = rec_sex_ast_node_int (node);
  868. break;
  869. }
  870. case REC_SEX_REAL:
  871. {
  872. res.type = REC_SEX_VAL_REAL;
  873. res.real_val = rec_sex_ast_node_real (node);
  874. break;
  875. }
  876. case REC_SEX_STR:
  877. {
  878. res.type = REC_SEX_VAL_STR;
  879. res.str_val = rec_sex_ast_node_str (node);
  880. break;
  881. }
  882. case REC_SEX_NAME:
  883. {
  884. rec_field_t field;
  885. const char *field_name;
  886. const char *field_subname;
  887. int index;
  888. bool tofix;
  889. if (rec_sex_ast_node_fixed (node))
  890. {
  891. res.type = REC_SEX_VAL_STR;
  892. res.str_val = rec_sex_ast_node_fixed_val (node);
  893. }
  894. else
  895. {
  896. field_name = rec_sex_ast_node_name (node);
  897. field_subname = rec_sex_ast_node_subname (node);
  898. index = rec_sex_ast_node_index (node);
  899. tofix = (index != -1);
  900. if (index == -1)
  901. {
  902. index = 0;
  903. }
  904. /* If there is a subname then the effective field name is
  905. the concatenation of the name and the subname separated
  906. by a '_' character. Otherwise it is just the name. */
  907. {
  908. if (field_subname)
  909. {
  910. char *effective_field_name = malloc (sizeof (char) *
  911. (strlen (field_name) + strlen (field_subname) + 2));
  912. memcpy (effective_field_name, field_name, strlen(field_name));
  913. effective_field_name[strlen(field_name)] = '_';
  914. memcpy (effective_field_name + strlen(field_name) + 1, field_subname, strlen(field_subname) + 1);
  915. field = rec_record_get_field_by_name (record, effective_field_name, index);
  916. }
  917. else
  918. {
  919. field = rec_record_get_field_by_name (record, field_name, index);
  920. }
  921. }
  922. res.type = REC_SEX_VAL_STR;
  923. if (field)
  924. {
  925. res.str_val = strdup (rec_field_value (field));
  926. }
  927. else
  928. {
  929. /* No field => "" */
  930. res.str_val = "";
  931. }
  932. if (tofix)
  933. {
  934. /* Make this node fixed. */
  935. rec_sex_ast_node_fix (node, res.str_val);
  936. }
  937. }
  938. break;
  939. }
  940. }
  941. return res;
  942. }
  943. static bool
  944. rec_sex_op_real_p (struct rec_sex_val_s op1,
  945. struct rec_sex_val_s op2)
  946. {
  947. bool ret;
  948. int integer;
  949. double real;
  950. ret = true;
  951. if ((op1.type == REC_SEX_VAL_INT)
  952. || ((op1.type == REC_SEX_VAL_STR)
  953. && rec_atoi (op1.str_val, &integer)))
  954. {
  955. /* Operand 1 is an integer. */
  956. switch (op2.type)
  957. {
  958. case REC_SEX_VAL_INT:
  959. {
  960. ret = false;
  961. break;
  962. }
  963. case REC_SEX_VAL_REAL:
  964. {
  965. ret = true;
  966. break;
  967. }
  968. case REC_SEX_VAL_STR:
  969. {
  970. ret = (rec_atod (op2.str_val, &real)
  971. && (!rec_atoi (op2.str_val, &integer)));
  972. break;
  973. }
  974. default:
  975. {
  976. ret = false;
  977. break;
  978. }
  979. }
  980. }
  981. if ((op1.type == REC_SEX_VAL_REAL)
  982. || ((op1.type == REC_SEX_VAL_STR)
  983. && rec_atod (op1.str_val, &real)
  984. && (!rec_atoi (op1.str_val, &integer))))
  985. {
  986. /* Operand 1 is a real. */
  987. switch (op2.type)
  988. {
  989. case REC_SEX_VAL_INT:
  990. {
  991. ret = true;
  992. break;
  993. }
  994. case REC_SEX_VAL_REAL:
  995. {
  996. ret = true;
  997. break;
  998. }
  999. case REC_SEX_VAL_STR:
  1000. {
  1001. ret = rec_atod (op2.str_val, &real);
  1002. break;
  1003. }
  1004. default:
  1005. {
  1006. ret = false;
  1007. break;
  1008. }
  1009. }
  1010. }
  1011. return ret;
  1012. }
  1013. /* End of rec-sex.c */