PageRenderTime 27ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/gsl/ggeval.c

https://github.com/sdon1011/Xitami-25
C | 1716 lines | 1424 code | 221 blank | 71 comment | 515 complexity | e1318bc811b6070c4943c16c15e3b116 MD5 | raw file
  1. /*===========================================================================*
  2. * *
  3. * ggeval.c - Script evaluator *
  4. * *
  5. * Copyright (c) 1991-2003 iMatix Corporation *
  6. * *
  7. * ------------------ GPL Licensed Source Code ------------------ *
  8. * iMatix makes this software available under the GNU General *
  9. * Public License (GPL) license for open source projects. For *
  10. * details of the GPL license please see www.gnu.org or read the *
  11. * file license.gpl provided in this package. *
  12. * *
  13. * This program is free software; you can redistribute it and/or *
  14. * modify it under the terms of the GNU General Public License as *
  15. * published by the Free Software Foundation; either version 2 of *
  16. * the License, or (at your option) any later version. *
  17. * *
  18. * This program is distributed in the hope that it will be useful, *
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  21. * GNU General Public License for more details. *
  22. * *
  23. * You should have received a copy of the GNU General Public *
  24. * License along with this program in the file 'license.gpl'; if *
  25. * not, write to the Free Software Foundation, Inc., 59 Temple *
  26. * Place - Suite 330, Boston, MA 02111-1307, USA. *
  27. * *
  28. * You can also license this software under iMatix's General Terms *
  29. * of Business (GTB) for commercial projects. If you have not *
  30. * explicitly licensed this software under the iMatix GTB you may *
  31. * only use it under the terms of the GNU General Public License. *
  32. * *
  33. * For more information, send an email to info@imatix.com. *
  34. * -------------------------------------------------------------- *
  35. *===========================================================================*/
  36. #include "sfl.h" /* Universal include file */
  37. #if defined (JAVASCRIPT)
  38. #include "ggjs.h" /* Support for Javascript */
  39. #endif
  40. #include "ggpars.h" /* Script parser header file */
  41. #include "ggeval.h" /* Include header file */
  42. /*- Types -------------------------------------------------------------------*/
  43. typedef int (EVAL_FUNCTION (SCRIPT_NODE *node));
  44. typedef struct {
  45. char
  46. name [16];
  47. int
  48. min_params,
  49. max_params;
  50. EVAL_FUNCTION
  51. *evaluate;
  52. } GSL_FUNCTION;
  53. /*- Function prototypes -----------------------------------------------------*/
  54. static int evaluate_substitute_node (SCRIPT_NODE *node);
  55. static void pretty_print (char *text,
  56. SCRIPT_NODE *pretty,
  57. char *example);
  58. static void strneat (char *text);
  59. static int evaluate_literal_node (SCRIPT_NODE *node);
  60. static int evaluate_number_node (SCRIPT_NODE *node);
  61. static int evaluate_operand_node (SCRIPT_NODE *node);
  62. static int evaluate_symbol_node (SCRIPT_NODE *node);
  63. static int evaluate_member_node (SCRIPT_NODE *node);
  64. static int evaluate_function_node (SCRIPT_NODE *node);
  65. static int eval_count (SCRIPT_NODE *node);
  66. static Bool verify_function_parameters
  67. (SCRIPT_NODE *fn_node, int min, int max);
  68. static int eval_env (SCRIPT_NODE *node);
  69. static int eval_index (SCRIPT_NODE *node);
  70. static SCOPE_BLOCK *lookup_data_scope_from_parameter (SCRIPT_NODE *node);
  71. static int eval_item (SCRIPT_NODE *node);
  72. static int eval_name (SCRIPT_NODE *node);
  73. static int eval_exists (SCRIPT_NODE *node);
  74. static int eval_timestamp (SCRIPT_NODE *node);
  75. static int eval_length (SCRIPT_NODE *node);
  76. static int eval_defined (SCRIPT_NODE *node);
  77. static int eval_deleted (SCRIPT_NODE *node);
  78. static int eval_substr (SCRIPT_NODE *node);
  79. static SCRIPT_NODE *function_parameter
  80. (SCRIPT_NODE *node, int n);
  81. static Bool node_is_countable (SCRIPT_NODE *node);
  82. static int eval_trim (SCRIPT_NODE *node);
  83. static int eval_justify (SCRIPT_NODE *node);
  84. static int eval_macro (SCRIPT_NODE *node);
  85. #if defined (JAVASCRIPT)
  86. static int evaluate_javascript_function (SCRIPT_NODE *node);
  87. #endif
  88. static int evaluate_operator (SCRIPT_NODE *node);
  89. static int evaluate_text_node (SCRIPT_NODE *node);
  90. /*- Global variables --------------------------------------------------------*/
  91. static GSL_FUNCTION gsl_functions [] =
  92. {
  93. {"count", 1, 2, eval_count},
  94. {"env", 1, 1, eval_env},
  95. {"index", 0, 1, eval_index},
  96. {"item", 0, 1, eval_item},
  97. {"name", 0, 1, eval_name},
  98. {"exists", 1, 1, eval_exists},
  99. {"timestamp", 1, 1, eval_timestamp},
  100. {"length", 1, 1, eval_length},
  101. {"defined", 1, 1, eval_defined},
  102. {"deleted", 0, 1, eval_deleted},
  103. {"substr", 2, 4, eval_substr},
  104. {"trim", 1, 1, eval_trim},
  105. {"justify", 3, 3, eval_justify},
  106. {"macro", 1, 1, eval_macro},
  107. {"", 0, 0, NULL}
  108. };
  109. /*- Functions ---------------------------------------------------------------*/
  110. int evaluate_script (SCRIPT_NODE *node)
  111. {
  112. int
  113. result;
  114. if (node)
  115. {
  116. result = evaluate_script_node (node);
  117. if (result)
  118. return result;
  119. if (node-> result_type == TYPE_UNDEFINED)
  120. {
  121. undefined_expression_error (node);
  122. return -1;
  123. }
  124. }
  125. return 0;
  126. }
  127. int
  128. evaluate_script_node (SCRIPT_NODE *node)
  129. {
  130. if (node == NULL)
  131. return 0;
  132. node-> indent = node-> spaces;
  133. if (node-> indent > shuffle)
  134. {
  135. if (node-> indent - node-> shuffle_in > shuffle)
  136. {
  137. node-> indent -= node-> shuffle_in;
  138. node-> shuffle_in = 0;
  139. }
  140. else
  141. {
  142. node-> shuffle_in -= (node-> indent - shuffle - 1);
  143. node-> indent = shuffle + 1;
  144. }
  145. }
  146. if (! node-> constant)
  147. {
  148. if (node-> type == GG_SUBSTITUTE)
  149. if (evaluate_substitute_node (node) != 0)
  150. return -1;
  151. if (node-> type == GG_LITERAL)
  152. if (evaluate_literal_node (node) != 0)
  153. return -1;
  154. if (node-> type == GG_NUMBER)
  155. if (evaluate_number_node (node) != 0)
  156. return -1;
  157. if (node-> type == GG_OPERAND)
  158. if (evaluate_operand_node (node) != 0)
  159. return -1;
  160. if (node-> type == GG_SYMBOL)
  161. if (evaluate_symbol_node (node) != 0)
  162. return -1;
  163. if (node-> type == GG_MEMBER)
  164. if (evaluate_member_node (node) != 0)
  165. return -1;
  166. if (node-> type == GG_CALL)
  167. if (evaluate_function_node (node) != 0)
  168. return -1;
  169. if (node-> type == GG_OPERATOR)
  170. if (evaluate_operator (node) != 0)
  171. return -1;
  172. if (node-> type == GG_TEXT)
  173. if (evaluate_text_node (node) != 0)
  174. return -1;
  175. }
  176. if (node-> line_break)
  177. node-> shuffle_out = 0;
  178. else
  179. if (node-> result_type == TYPE_STRING)
  180. node-> shuffle_out = node-> shuffle_in
  181. + strlen (node-> result_s)
  182. - node-> length;
  183. return 0;
  184. }
  185. static int
  186. evaluate_substitute_node (SCRIPT_NODE *node)
  187. {
  188. char
  189. buffer [LINE_MAX + 1],
  190. *example = NULL;
  191. int
  192. length;
  193. SCRIPT_NODE
  194. *symbol_node;
  195. if (evaluate_script_node (node-> op1) != 0)
  196. return -1;
  197. if (evaluate_script_node (node-> pretty) != 0)
  198. return -1;
  199. if (evaluate_script_node (node-> format) != 0)
  200. return -1;
  201. node-> constant = node-> op1-> constant
  202. && (node-> pretty ? node-> pretty-> constant : TRUE)
  203. && (node-> format ? node-> format-> constant : TRUE);
  204. copy_result (node, node-> op1);
  205. /* Only match the case if ignorecase is TRUE and the expression */
  206. /* consists of a single identifier, possibly with a default clause. */
  207. if (node-> result_type == TYPE_STRING)
  208. {
  209. if (ignorecase)
  210. {
  211. symbol_node = node-> op1;
  212. if ((symbol_node-> type == GG_OPERATOR)
  213. && (symbol_node-> operator == OP_DEFAULT))
  214. symbol_node = symbol_node-> op1;
  215. if ((symbol_node-> type == GG_SYMBOL)
  216. && (symbol_node-> op2))
  217. example = string_result (symbol_node-> op2);
  218. }
  219. pretty_print (node-> result_s, node-> pretty, example);
  220. }
  221. if (node-> op1-> result_type == TYPE_UNDEFINED)
  222. {
  223. /* A top-level default operator with no second operand means don't */
  224. /* panic about NULL */
  225. if ((node-> op1-> type == GG_OPERATOR)
  226. && (node-> op1-> operator == OP_DEFAULT)
  227. && (node-> op1-> op2 == NULL))
  228. {
  229. node-> result_type = TYPE_STRING;
  230. node-> result_s = mem_strdup ("");
  231. }
  232. else
  233. node-> culprit = node-> op1-> culprit;
  234. }
  235. if (node-> format)
  236. {
  237. length = format_output (buffer, LINE_MAX, node);
  238. if (length < 0)
  239. return -1;
  240. mem_free (node-> result_s);
  241. node-> result_s = mem_alloc (length + 1);
  242. ASSERT (node-> result_s);
  243. strcpy (node-> result_s, buffer);
  244. node-> result_type = TYPE_STRING;
  245. }
  246. return 0;
  247. }
  248. /* pretty_print: Reformats a string according to a format string consisting */
  249. /* of a comma-separated series of specifiers. Currently accepted formats: */
  250. /* lower - lower case */
  251. /* UPPER - UPPER CASE */
  252. /* Neat - Neat Case */
  253. /* c - Valid_c_identifier */
  254. /* COBOL - VALID-COBOL-IDENTIFIER */
  255. /* */
  256. /* If no case modifier is provided and pretty is not empty and the expr- */
  257. /* is a single identifier, its case is used as an example to match for */
  258. /* lower, upper or neat case. */
  259. static void
  260. pretty_print (char *text, SCRIPT_NODE *pretty, char *example)
  261. {
  262. char
  263. *tokens,
  264. *token,
  265. *c;
  266. Bool
  267. use_example;
  268. ASSERT (text);
  269. if (*text == 0) /* Do nothing to null string */
  270. return;
  271. use_example = (example != NULL);
  272. if (pretty)
  273. {
  274. if (strlen (string_result (pretty)) == 0)
  275. use_example = FALSE;
  276. tokens = mem_strdup (pretty-> result_s);
  277. token = strtok (tokens, ", ");
  278. while (token)
  279. {
  280. strlwc (token);
  281. if (streq (token, "lower"))
  282. {
  283. use_example = FALSE;
  284. strlwc (text);
  285. }
  286. else
  287. if (streq (token, "upper"))
  288. {
  289. use_example = FALSE;
  290. strupc (text);
  291. }
  292. else
  293. if (streq (token, "neat"))
  294. {
  295. use_example = FALSE;
  296. strneat (text);
  297. }
  298. else
  299. if (streq (token, "c"))
  300. {
  301. c = text;
  302. if (!isalpha (*c))
  303. *c = '_';
  304. while (*c)
  305. {
  306. if (!(isalpha (*c) || isdigit (*c)))
  307. *c = '_';
  308. c++;
  309. }
  310. }
  311. else
  312. if (streq (token, "cobol"))
  313. {
  314. c = text;
  315. if (!isalpha (*c))
  316. *c = '-';
  317. while (*c)
  318. {
  319. if (!(isalpha (*c) || isdigit (*c)))
  320. *c = '-';
  321. c++;
  322. }
  323. }
  324. token = strtok (NULL, ", ");
  325. }
  326. mem_free (tokens);
  327. }
  328. if ((use_example)
  329. && (strlen (example) > 1))
  330. {
  331. c = example;
  332. if (isupper (*c))
  333. while ((isupper (*c) || !isalpha (*c)) && (*c))
  334. c++;
  335. if (*c == 0)
  336. strupc (text);
  337. else
  338. if (c == example + 1)
  339. {
  340. if (islower (*c))
  341. {
  342. while ((islower (*c) || !isalpha (*c)) && (*c))
  343. c++;
  344. if (!isupper (*c))
  345. strneat (text);
  346. }
  347. }
  348. else
  349. if (c == example)
  350. {
  351. if (islower (*c))
  352. while ((islower (*c) || !isalpha (*c)) && (*c))
  353. c++;
  354. if (*c == 0)
  355. strlwc (text);
  356. }
  357. }
  358. }
  359. static void
  360. strneat (char *text)
  361. {
  362. char
  363. *c;
  364. c = text;
  365. while (*c)
  366. {
  367. while ((!isalpha (*c)) && (*c))
  368. c++;
  369. *c = toupper (*c);
  370. c++;
  371. while (isalpha (*c) && (*c))
  372. {
  373. *c = tolower (*c);
  374. c++;
  375. }
  376. }
  377. }
  378. static int
  379. evaluate_literal_node (SCRIPT_NODE *node)
  380. {
  381. if (evaluate_script_node (node-> op1) != 0)
  382. return -1;
  383. node-> constant = node-> op1-> constant;
  384. node-> result_type = node-> op1-> result_type;
  385. if (node-> op1-> result_s)
  386. {
  387. node-> result_s = mem_alloc (node-> op1-> indent +
  388. strlen (node-> op1-> result_s) + 1);
  389. memset (node-> result_s, ' ', node-> op1-> indent);
  390. strcpy (node-> result_s + node-> op1-> indent,
  391. node-> op1-> result_s);
  392. }
  393. node-> result_n = node-> op1-> result_n;
  394. node-> culprit = node-> op1-> culprit;
  395. return 0;
  396. }
  397. static int
  398. evaluate_number_node (SCRIPT_NODE *node)
  399. {
  400. if (evaluate_script_node (node-> op1) != 0)
  401. return -1;
  402. if (evaluate_script_node (node-> op2) != 0)
  403. return -1;
  404. node-> constant = (node-> op1 ? node-> op1-> constant : TRUE)
  405. && (node-> op2 ? node-> op2-> constant : TRUE);
  406. node-> result_s = mem_alloc (
  407. (node-> op1 ? strlen (node-> op1-> result_s) : 1)
  408. + (node-> operator == OP_MINUS ? 1 : 0)
  409. + (node-> op2 ? strlen (node-> op2-> result_s) + 1 : 0)
  410. + 1);
  411. ASSERT (node-> result_s);
  412. node-> result_s [0] = '\0';
  413. if (node-> operator == OP_MINUS)
  414. strcat (node-> result_s, "-");
  415. strcat (node-> result_s, node-> op1 ? node-> op1-> result_s : "0");
  416. if (node-> op2)
  417. {
  418. strcat (node-> result_s, ".");
  419. strcat (node-> result_s, node-> op2-> result_s);
  420. }
  421. node-> result_type = TYPE_STRING;
  422. number_result (node);
  423. return 0;
  424. }
  425. static int
  426. evaluate_operand_node (SCRIPT_NODE *node)
  427. {
  428. int
  429. rc;
  430. if (evaluate_script (node-> op2) != 0)
  431. return -1;
  432. if (! node-> op2-> constant)
  433. {
  434. gg_free (node-> op3);
  435. node-> op3 = NULL;
  436. }
  437. if (! node-> op3)
  438. node-> op3 = gg_parse_expression (string_result (node-> op2));
  439. if (node-> op3)
  440. {
  441. rc = evaluate_script_node (node-> op3);
  442. if (rc == 0)
  443. {
  444. copy_result (node, node-> op3);
  445. node-> indent = node-> op3-> indent;
  446. node-> constant = node-> op2-> constant
  447. && node-> op3-> constant;
  448. }
  449. return rc;
  450. }
  451. else
  452. {
  453. gg_report_error ('E', "Error in operand: %s",
  454. node-> op2-> result_s);
  455. gg_report_error ('E', "%s", gg_error ());
  456. return -1;
  457. }
  458. return 0;
  459. }
  460. static int
  461. evaluate_symbol_node (SCRIPT_NODE *node)
  462. {
  463. if (node-> op1)
  464. {
  465. if (evaluate_script_node (node-> op1) != 0)
  466. return -1;
  467. if (node-> op1-> result_type == TYPE_UNDEFINED)
  468. {
  469. node-> result_type = TYPE_UNDEFINED;
  470. node-> culprit = node-> op1-> culprit;
  471. return 0;
  472. }
  473. }
  474. if (node-> op2)
  475. {
  476. if (evaluate_script_node (node-> op2) != 0)
  477. return -1;
  478. if (node-> op2-> result_type == TYPE_UNDEFINED)
  479. {
  480. node-> result_type = TYPE_UNDEFINED;
  481. node-> culprit = node-> op2-> culprit;
  482. return 0;
  483. }
  484. }
  485. node-> result_s = mem_strdup (symbol_value (node));
  486. if (node-> result_s)
  487. node-> result_type = TYPE_STRING;
  488. else
  489. {
  490. node-> result_type = TYPE_UNDEFINED;
  491. node-> culprit = node;
  492. }
  493. return 0;
  494. }
  495. static int
  496. evaluate_member_node (SCRIPT_NODE *node)
  497. {
  498. if (evaluate_script_node (node-> op1) != 0)
  499. return -1;
  500. if (evaluate_script_node (node-> op2) != 0)
  501. return -1;
  502. node-> constant = (node-> op1 ? node-> op1-> constant : TRUE)
  503. && (node-> op2 ? node-> op2-> constant : TRUE);
  504. if (node-> op2 && node-> op2-> result_type == TYPE_UNDEFINED)
  505. {
  506. node-> result_type = TYPE_UNDEFINED;
  507. node-> culprit = node-> op2-> culprit;
  508. }
  509. else
  510. if (node-> op1 && node-> op1-> result_type == TYPE_UNDEFINED)
  511. {
  512. node-> result_type = TYPE_UNDEFINED;
  513. node-> culprit = node-> op1-> culprit;
  514. }
  515. else
  516. node-> result_type = TYPE_OK;
  517. return 0;
  518. }
  519. static int
  520. evaluate_function_node (SCRIPT_NODE *node)
  521. {
  522. GSL_FUNCTION
  523. gsl_function;
  524. int
  525. i;
  526. if (evaluate_script_node (node-> op2) != 0)
  527. return -1;
  528. strlwc (string_result (node-> op2));
  529. i = 0;
  530. gsl_function = gsl_functions [i];
  531. while (gsl_function. evaluate != NULL)
  532. {
  533. if (streq (node-> op2-> result_s, gsl_function. name))
  534. break;
  535. i++;
  536. gsl_function = gsl_functions [i];
  537. }
  538. if (gsl_function. evaluate != NULL)
  539. if (verify_function_parameters (node-> op3,
  540. gsl_function. min_params,
  541. gsl_function. max_params))
  542. return gsl_function. evaluate (node);
  543. else
  544. return -1;
  545. else
  546. #if defined (JAVASCRIPT)
  547. return evaluate_javascript_function (node);
  548. #else
  549. {
  550. gg_report_error ('E', "Unknown function: %s", node-> op2-> result_s);
  551. return -1;
  552. }
  553. #endif
  554. }
  555. static Bool
  556. verify_function_parameters (SCRIPT_NODE *fn_node, int min, int max)
  557. {
  558. int
  559. count;
  560. SCRIPT_NODE
  561. *node;
  562. count = 0;
  563. node = fn_node;
  564. if (node)
  565. count++;
  566. while (node != NULL)
  567. {
  568. if ((node-> type == GG_OPERATOR)
  569. && (node-> operator == OP_NEXT_ARG))
  570. {
  571. count++;
  572. node = node-> op1;
  573. }
  574. else
  575. break;
  576. }
  577. if (count < min)
  578. {
  579. gg_report_error ('E', "Missing function parameter.");
  580. return FALSE;
  581. }
  582. if (count > max)
  583. {
  584. gg_report_error ('E', "Too many function parameters.");
  585. return FALSE;
  586. }
  587. return TRUE;
  588. }
  589. static int
  590. eval_count (SCRIPT_NODE *node)
  591. {
  592. long
  593. item,
  594. n;
  595. SCRIPT_NODE
  596. *identifier,
  597. *condition;
  598. char
  599. *name,
  600. *xml_name;
  601. SCOPE_BLOCK
  602. *for_block;
  603. SCOPE_ITEM
  604. *scope_item;
  605. XML_ITEM
  606. *from_xml,
  607. *xml_item;
  608. Bool
  609. error = FALSE;
  610. identifier = function_parameter (node-> op3, 1);
  611. condition = function_parameter (node-> op3, 2);
  612. if (identifier-> type == GG_SYMBOL)
  613. {
  614. if ((evaluate_script_node (identifier-> op1) != 0)
  615. || (evaluate_script_node (identifier-> op2) != 0))
  616. return -1;
  617. from_xml = lookup_from_xml (identifier-> op1);
  618. if (! from_xml)
  619. return -1;
  620. name = (identifier-> op2) ? string_result (identifier-> op2) : NULL;
  621. }
  622. else
  623. {
  624. gg_report_error ('E', "Function argument must be an identifier.");
  625. return -1;
  626. }
  627. n = 0;
  628. if (from_xml)
  629. {
  630. for_block = create_scope_block ("count");
  631. for_block-> children = TRUE;
  632. xml_item = xml_first_child (from_xml);
  633. item = 0;
  634. while (xml_item)
  635. {
  636. while (xml_item)
  637. {
  638. xml_name = xml_item_name (xml_item);
  639. if (xml_name && name)
  640. {
  641. if (ignorecase)
  642. {
  643. if (lexcmp (xml_name, name) == 0)
  644. break;
  645. }
  646. else
  647. {
  648. if (streq (xml_name, name))
  649. break;
  650. }
  651. }
  652. else
  653. /* Take all named children; others are part of value */
  654. if (xml_name && (! name))
  655. break;
  656. xml_item = xml_next_sibling (xml_item);
  657. }
  658. item++;
  659. if (xml_item)
  660. {
  661. if (condition)
  662. {
  663. scope_item = create_scope_item (for_block, xml_item, item);
  664. for_block-> scope_item = scope_item;
  665. for_block-> xml_item = xml_item;
  666. if (evaluate_script (condition) != 0)
  667. {
  668. error = TRUE;
  669. break;
  670. }
  671. number_result (condition);
  672. if ((condition-> result_type == TYPE_NUMBER)
  673. && (condition-> result_n != 0))
  674. n++;
  675. gg_clean (condition);
  676. }
  677. else
  678. n++;
  679. xml_item = xml_next_sibling (xml_item);
  680. }
  681. }
  682. destroy_scope_block ();
  683. if (error)
  684. return -1;
  685. }
  686. node-> result_type = TYPE_NUMBER;
  687. node-> result_n = n;
  688. return 0;
  689. }
  690. static int
  691. eval_env (SCRIPT_NODE *node)
  692. {
  693. if (evaluate_script_node (node-> op3) != 0)
  694. return -1;
  695. if (node-> op3-> result_type != TYPE_UNDEFINED)
  696. {
  697. node-> result_type = TYPE_STRING;
  698. node-> result_s = mem_strdup (getenv (string_result (node-> op3)));
  699. }
  700. else
  701. {
  702. node-> result_type = TYPE_UNDEFINED;
  703. node-> culprit = node-> op3;
  704. }
  705. return 0;
  706. }
  707. static int
  708. eval_index (SCRIPT_NODE *node)
  709. {
  710. SCOPE_BLOCK
  711. *scope_block;
  712. scope_block = lookup_data_scope_from_parameter (node);
  713. if (! scope_block)
  714. return -1;
  715. if (scope_block-> index)
  716. {
  717. node-> result_type = TYPE_NUMBER;
  718. node-> result_n = scope_block-> index;
  719. }
  720. else
  721. node-> result_type = TYPE_UNDEFINED;
  722. return 0;
  723. }
  724. SCOPE_BLOCK *
  725. lookup_data_scope_from_parameter (SCRIPT_NODE *node)
  726. {
  727. SCOPE_BLOCK
  728. *scope_block;
  729. if (node-> op3)
  730. if ((node-> op3-> type == GG_OPERAND)
  731. || (node-> op3-> type == GG_SYMBOL))
  732. {
  733. if (evaluate_script_node (node-> op3-> op2) != 0)
  734. return NULL;
  735. if (node-> op3-> op1)
  736. {
  737. gg_report_error ('E', "Invalid scope.");
  738. return NULL;
  739. }
  740. scope_block = lookup_scope_block (string_result (node-> op3-> op2));
  741. if (! scope_block)
  742. {
  743. gg_report_error ('E', "Unknown data scope: %s",
  744. node-> op3-> op2-> result_s);
  745. return NULL;
  746. }
  747. }
  748. else
  749. if (node-> op3-> type == GG_NUMBER)
  750. {
  751. if (evaluate_script_node (node-> op3) != 0)
  752. return NULL;
  753. scope_block = lookup_scope_block (string_result (node-> op3));
  754. if (! scope_block)
  755. {
  756. gg_report_error ('E', "Unknown data scope: %s",
  757. node-> op3-> result_s);
  758. return NULL;
  759. }
  760. }
  761. else
  762. {
  763. gg_report_error ('E', "Argument must be a legal identifier.");
  764. return NULL;
  765. }
  766. else
  767. {
  768. FORLIST (scope_block, scope_stack)
  769. if (scope_block-> children)
  770. break;
  771. if ((void *) scope_block == & scope_stack)
  772. {
  773. gg_report_error ('E', "No data scope.");
  774. return NULL;
  775. }
  776. }
  777. return scope_block;
  778. }
  779. static int
  780. eval_item (SCRIPT_NODE *node)
  781. {
  782. SCOPE_BLOCK
  783. *scope_block;
  784. scope_block = lookup_data_scope_from_parameter (node);
  785. if (! scope_block)
  786. return -1;
  787. node-> result_type = TYPE_NUMBER;
  788. node-> result_n = scope_block-> scope_item-> item;
  789. return 0;
  790. }
  791. static int
  792. eval_name (SCRIPT_NODE *node)
  793. {
  794. SCOPE_BLOCK
  795. *scope_block;
  796. scope_block = lookup_data_scope_from_parameter (node);
  797. if (! scope_block)
  798. return -1;
  799. if ((scope_block-> xml_item)
  800. && (xml_item_name (scope_block-> xml_item)))
  801. {
  802. node-> result_type = TYPE_STRING;
  803. node-> result_s = mem_strdup (
  804. xml_item_name (scope_block-> xml_item));
  805. }
  806. else
  807. node-> result_type = TYPE_UNDEFINED;
  808. return 0;
  809. }
  810. static int
  811. eval_exists (SCRIPT_NODE *node)
  812. {
  813. if (evaluate_script_node (node-> op3) != 0)
  814. return -1;
  815. node-> result_type = TYPE_NUMBER;
  816. node-> result_n = file_exists (string_result (node-> op3)) ? 1 : 0;
  817. return 0;
  818. }
  819. static int
  820. eval_timestamp (SCRIPT_NODE *node)
  821. {
  822. char
  823. buffer [LINE_MAX + 1];
  824. time_t
  825. timer;
  826. if (evaluate_script_node (node-> op3) != 0)
  827. return -1;
  828. timer = get_file_time (string_result (node-> op3));
  829. if (timer)
  830. {
  831. node-> result_type = TYPE_STRING;
  832. sprintf (buffer, "%ld%ld", timer_to_date (timer),
  833. timer_to_time (timer));
  834. node-> result_s = mem_strdup (buffer);
  835. ASSERT (node-> result_s);
  836. }
  837. return 0;
  838. }
  839. static int
  840. eval_length (SCRIPT_NODE *node)
  841. {
  842. if (evaluate_script_node (node-> op3) != 0)
  843. return -1;
  844. node-> constant = node-> op2-> constant
  845. && node-> op3-> constant;
  846. if (node-> op3)
  847. if (node-> op3-> result_type != TYPE_UNDEFINED)
  848. {
  849. node-> result_type = TYPE_NUMBER;
  850. node-> result_n = strlen (string_result (node-> op3));
  851. }
  852. else
  853. {
  854. node-> result_type = TYPE_UNDEFINED;
  855. node-> culprit = node-> op3-> culprit;
  856. }
  857. else
  858. node-> result_type = TYPE_UNDEFINED;
  859. return 0;
  860. }
  861. static int
  862. eval_defined (SCRIPT_NODE *node)
  863. {
  864. if (evaluate_script_node (node-> op3) != 0)
  865. return -1;
  866. node-> result_n = (node-> op3-> result_type != TYPE_UNDEFINED) ? 1 : 0;
  867. node-> result_type = TYPE_NUMBER;
  868. return 0;
  869. }
  870. static int
  871. eval_deleted (SCRIPT_NODE *node)
  872. {
  873. SCOPE_BLOCK
  874. *scope_block;
  875. scope_block = lookup_data_scope_from_parameter (node);
  876. if (! scope_block)
  877. return -1;
  878. node-> result_n = (scope_block-> xml_item == NULL) ? 1 : 0;
  879. node-> result_type = TYPE_NUMBER;
  880. return 0;
  881. }
  882. static int
  883. eval_substr (SCRIPT_NODE *node)
  884. {
  885. SCRIPT_NODE
  886. *string,
  887. *start,
  888. *end,
  889. *len;
  890. unsigned long
  891. start_n = 0,
  892. end_n = 0,
  893. len_n = 0;
  894. string = function_parameter (node-> op3, 1);
  895. start = function_parameter (node-> op3, 2);
  896. end = function_parameter (node-> op3, 3);
  897. len = function_parameter (node-> op3, 4);
  898. if (evaluate_script_node (string) != 0)
  899. return -1;
  900. if (string-> result_type == TYPE_UNDEFINED)
  901. {
  902. node-> culprit = string-> culprit;
  903. return 0;
  904. }
  905. else
  906. string_result (string);
  907. if (start && end && len)
  908. {
  909. gg_report_error ('E', "Too many parameters for function 'substr'.");
  910. return -1;
  911. }
  912. if (!(start || end || len))
  913. {
  914. gg_report_error ('E', "Not enough parameters for function 'substr'.");
  915. return -1;
  916. }
  917. if (start)
  918. {
  919. if (evaluate_script_node (start) != 0)
  920. return -1;
  921. if (node_is_countable (start))
  922. start_n = (unsigned long) start-> result_n;
  923. else
  924. {
  925. gg_report_error ('E', "Illegal 'Start' value: %s",
  926. string_result (start));
  927. return -1;
  928. }
  929. }
  930. if (end)
  931. {
  932. if (evaluate_script_node (end) != 0)
  933. return -1;
  934. if (node_is_countable (end))
  935. end_n = (unsigned long) end-> result_n;
  936. else
  937. {
  938. gg_report_error ('E', "Illegal 'End' value: %s",
  939. string_result (end));
  940. return -1;
  941. }
  942. }
  943. if (len)
  944. {
  945. if (evaluate_script_node (len) != 0)
  946. return -1;
  947. if (node_is_countable (len))
  948. len_n = (unsigned long) len-> result_n;
  949. else
  950. {
  951. gg_report_error ('E', "Illegal 'Len' value: %s",
  952. string_result (len));
  953. return -1;
  954. }
  955. }
  956. if (start && end
  957. && (end_n < start_n))
  958. {
  959. gg_report_error ('E', "'End' must be at least 'Start' in 'substr'");
  960. return -1;
  961. }
  962. if (len && !start)
  963. {
  964. if (!end)
  965. end_n = strlen (string-> result_s) - 1;
  966. start_n = end_n - len_n + 1;
  967. }
  968. else
  969. {
  970. if (!start)
  971. start_n = 0;
  972. if (!len)
  973. {
  974. if (end)
  975. len_n = end_n - start_n + 1;
  976. else
  977. len_n = strlen (string-> result_s);
  978. }
  979. }
  980. if (start_n >= strlen (string-> result_s))
  981. node-> result_s = mem_strdup ("");
  982. else
  983. {
  984. node-> result_s = mem_alloc (len_n + 1);
  985. if (start_n >= 0)
  986. strncpy (node-> result_s, & string-> result_s [start_n], len_n);
  987. else
  988. strncpy (node-> result_s, string-> result_s, len_n);
  989. (node-> result_s) [len_n] = '\0';
  990. }
  991. node-> result_type = TYPE_STRING;
  992. node-> constant = node-> op2-> constant
  993. && (string ? string-> constant : TRUE)
  994. && (start ? start -> constant : TRUE)
  995. && (end ? end -> constant : TRUE)
  996. && (len ? len -> constant : TRUE);
  997. return 0;
  998. }
  999. /* Return n-th function parameter */
  1000. static SCRIPT_NODE *
  1001. function_parameter (SCRIPT_NODE *node, int n)
  1002. {
  1003. int
  1004. count = 0;
  1005. if ((node)
  1006. && (node-> type == GG_OPERATOR)
  1007. && (node-> operator == OP_NEXT_ARG))
  1008. {
  1009. count++;
  1010. while ((node-> op1)
  1011. && (node-> op1-> type == GG_OPERATOR)
  1012. && (node-> op1-> operator == OP_NEXT_ARG))
  1013. {
  1014. node = node-> op1;
  1015. count++;
  1016. }
  1017. }
  1018. if (n > count + 1)
  1019. return NULL;
  1020. while (n > 2)
  1021. {
  1022. node = node-> parent;
  1023. n--;
  1024. }
  1025. if (n == 1)
  1026. if ((node-> type == GG_OPERATOR)
  1027. && (node-> operator == OP_NEXT_ARG))
  1028. return node-> op1;
  1029. else
  1030. return node;
  1031. else
  1032. return node-> op2;
  1033. }
  1034. static Bool
  1035. node_is_countable (SCRIPT_NODE *node)
  1036. {
  1037. if (node)
  1038. {
  1039. if (node-> result_type != TYPE_UNDEFINED)
  1040. {
  1041. number_result (node);
  1042. if ((node-> result_type == TYPE_NUMBER)
  1043. && (node-> result_n == floor (node-> result_n))
  1044. && (node-> result_n >= 0))
  1045. return TRUE;
  1046. }
  1047. else
  1048. undefined_expression_error (node);
  1049. }
  1050. return FALSE;
  1051. }
  1052. static int
  1053. eval_trim (SCRIPT_NODE *node)
  1054. {
  1055. if (evaluate_script_node (node-> op3) != 0)
  1056. return -1;
  1057. node-> constant = node-> op2-> constant
  1058. && node-> op3-> constant;
  1059. node-> result_type = node-> op3-> result_type;
  1060. if (node-> op3-> result_s)
  1061. {
  1062. node-> result_s = mem_strdup (trim (node-> op3-> result_s));
  1063. ASSERT (node-> result_s);
  1064. }
  1065. node-> result_n = node-> op3-> result_n;
  1066. node-> culprit = node-> op3-> culprit;
  1067. return 0;
  1068. }
  1069. static int
  1070. eval_justify (SCRIPT_NODE *node)
  1071. {
  1072. SCRIPT_NODE
  1073. *string,
  1074. *width,
  1075. *prefix;
  1076. unsigned long
  1077. width_n;
  1078. string = function_parameter (node-> op3, 1);
  1079. width = function_parameter (node-> op3, 2);
  1080. prefix = function_parameter (node-> op3, 3);
  1081. if (evaluate_script_node (string) != 0)
  1082. return -1;
  1083. if (evaluate_script_node (prefix) != 0)
  1084. return -1;
  1085. if (evaluate_script_node (width) != 0)
  1086. return -1;
  1087. node-> constant = (node-> op2-> constant
  1088. && (string ? string-> constant : TRUE)
  1089. && (width ? width -> constant : TRUE)
  1090. && (prefix ? prefix-> constant : TRUE));
  1091. if (node_is_countable (width))
  1092. width_n = (unsigned long) width-> result_n;
  1093. else
  1094. {
  1095. gg_report_error ('E', "Illegal 'Width' value: %s",
  1096. string_result (width));
  1097. return -1;
  1098. }
  1099. node-> result_s =
  1100. strreformat (string_result (string),
  1101. width_n,
  1102. string_result (prefix));
  1103. node-> result_type = TYPE_STRING;
  1104. return 0;
  1105. }
  1106. static int
  1107. eval_macro (SCRIPT_NODE *node)
  1108. {
  1109. if (evaluate_script_node (node-> op3) != 0)
  1110. return -1;
  1111. node-> result_type = TYPE_NUMBER;
  1112. if (sym_lookup_symbol (macros, string_result (node-> op3)))
  1113. node-> result_n = 1;
  1114. else
  1115. node-> result_n = 0;
  1116. return 0;
  1117. }
  1118. #if defined (JAVASCRIPT)
  1119. static int
  1120. evaluate_javascript_function (SCRIPT_NODE *node)
  1121. {
  1122. SCRIPT_NODE
  1123. *param_node = node-> op3;
  1124. int
  1125. count = 0,
  1126. length = 0;
  1127. char
  1128. *js_text;
  1129. JSScript
  1130. *script;
  1131. jsval
  1132. result;
  1133. if (param_node)
  1134. {
  1135. while ((param_node-> type == GG_OPERATOR)
  1136. && (param_node-> operator == OP_NEXT_ARG))
  1137. {
  1138. if (evaluate_script_node (param_node-> op3) != 0)
  1139. return -1;
  1140. count ++;
  1141. if (param_node-> op3)
  1142. {
  1143. number_result (param_node-> op3);
  1144. if (param_node-> op3-> result_type != TYPE_UNDEFINED)
  1145. length += strlen (string_result (param_node-> op3));
  1146. if (param_node-> op3-> result_type == TYPE_STRING)
  1147. length += 2;
  1148. }
  1149. if (param_node-> op1)
  1150. param_node = param_node-> op1;
  1151. else
  1152. break;
  1153. }
  1154. count ++;
  1155. if ((param_node-> type != GG_OPERATOR)
  1156. || (param_node-> operator != OP_NEXT_ARG))
  1157. {
  1158. if (evaluate_script_node (param_node) != 0)
  1159. return -1;
  1160. if (param_node)
  1161. {
  1162. number_result (param_node);
  1163. if (param_node-> result_type != TYPE_UNDEFINED)
  1164. length += strlen (string_result (param_node));
  1165. if (param_node-> result_type == TYPE_STRING)
  1166. length += 2;
  1167. }
  1168. }
  1169. }
  1170. length += strlen (node-> op1-> result_s) + count + 1;
  1171. if (count == 0)
  1172. length ++;
  1173. js_text = mem_alloc (length + 1);
  1174. ASSERT (js_text);
  1175. strcpy (js_text, node-> op1-> result_s);
  1176. strcat (js_text, "(");
  1177. if (count > 0)
  1178. {
  1179. if ((param_node-> type != GG_OPERATOR)
  1180. || (param_node-> operator != OP_NEXT_ARG))
  1181. {
  1182. if (param_node-> result_type == TYPE_STRING)
  1183. strcat (js_text, "\"");
  1184. if (param_node-> result_type != TYPE_UNDEFINED)
  1185. strcat (js_text, param_node-> result_s);
  1186. if (param_node-> result_type == TYPE_STRING)
  1187. strcat (js_text, "\"");
  1188. param_node = param_node-> parent;
  1189. }
  1190. while (param_node != node)
  1191. {
  1192. if (param_node-> op3)
  1193. {
  1194. if (param_node-> op3-> result_type == TYPE_STRING)
  1195. strcat (js_text, ",\"");
  1196. if (param_node-> op3-> result_type != TYPE_UNDEFINED)
  1197. strcat (js_text, param_node-> op3-> result_s);
  1198. if (param_node-> op3-> result_type == TYPE_STRING)
  1199. strcat (js_text, "\"");
  1200. }
  1201. else
  1202. strcat (js_text, ",");
  1203. param_node = param_node-> parent;
  1204. }
  1205. }
  1206. strcat (js_text, ")");
  1207. script = JS_CompileScript (cx, obj,
  1208. js_text, length,
  1209. NULL, 0);
  1210. mem_free (js_text);
  1211. if (!script)
  1212. return -1;
  1213. if (JS_ExecuteScript(cx, obj, script, &result))
  1214. {
  1215. node-> result_s = mem_strdup (
  1216. JS_GetStringBytes (
  1217. JS_ValueToString(cx, result)));
  1218. node-> result_type = TYPE_STRING;
  1219. }
  1220. else
  1221. node-> result_type = TYPE_UNDEFINED;
  1222. JS_DestroyScript(cx, script);
  1223. return 0;
  1224. }
  1225. #endif
  1226. static int
  1227. evaluate_operator (SCRIPT_NODE *node)
  1228. {
  1229. OPERATOR
  1230. the_operator = node-> operator;
  1231. double
  1232. n = 0;
  1233. long
  1234. i;
  1235. Bool
  1236. safe;
  1237. int
  1238. offset,
  1239. length,
  1240. cmp;
  1241. node-> line_break = node-> op2 ? node-> op2-> line_break : FALSE;
  1242. node-> extend = node-> op2 ? node-> op2-> extend : FALSE;
  1243. node-> result_type = TYPE_UNDEFINED;
  1244. node-> result_s = NULL;
  1245. node-> culprit = NULL;
  1246. if (the_operator == OP_NEXT_ARG)
  1247. {
  1248. if (evaluate_script_node (node-> op1) != 0)
  1249. return -1;
  1250. if (evaluate_script_node (node-> op2) != 0)
  1251. return -1;
  1252. return 0;
  1253. }
  1254. safe = ((the_operator == OP_SAFE_EQUALS)
  1255. || (the_operator == OP_SAFE_NOT_EQUALS)
  1256. || (the_operator == OP_SAFE_GREATER_THAN)
  1257. || (the_operator == OP_SAFE_LESS_THAN)
  1258. || (the_operator == OP_SAFE_GREATER_EQUAL)
  1259. || (the_operator == OP_SAFE_LESS_EQUAL));
  1260. /* Evaluate first operand */
  1261. if (the_operator == OP_UNDEFINED)
  1262. node-> op1-> shuffle_in = node-> shuffle_in;
  1263. if (evaluate_script_node (node-> op1) != 0)
  1264. return -1;
  1265. node-> constant = (node-> op1 ? node-> op1-> constant : TRUE);
  1266. if (node-> op1)
  1267. {
  1268. /* Now try some optimisation. This also allows for */
  1269. /* constructs such as '.if defined (N) & N = 1' */
  1270. if ((the_operator == OP_OR) || (the_operator == OP_AND))
  1271. {
  1272. number_result (node-> op1);
  1273. if (node-> op1-> result_type == TYPE_NUMBER)
  1274. {
  1275. if ((the_operator == OP_OR)
  1276. && (node-> op1-> result_n != 0))
  1277. {
  1278. node-> result_type = TYPE_NUMBER;
  1279. node-> result_n = 1;
  1280. return 0;
  1281. }
  1282. else
  1283. if ((the_operator == OP_AND)
  1284. && (node-> op1-> result_n == 0))
  1285. {
  1286. node-> result_type = TYPE_NUMBER;
  1287. node-> result_n = 0;
  1288. return 0;
  1289. }
  1290. }
  1291. }
  1292. if (node-> op1-> result_type == TYPE_UNDEFINED)
  1293. {
  1294. if (the_operator == OP_DEFAULT)
  1295. {
  1296. if (evaluate_script_node (node-> op2) != 0)
  1297. return -1;
  1298. node-> constant &= (node-> op2 ? node-> op2-> constant : TRUE);
  1299. copy_result (node, node-> op2);
  1300. return 0;
  1301. }
  1302. else
  1303. if (! safe)
  1304. {
  1305. node-> culprit = node-> op1-> culprit;
  1306. return 0;
  1307. }
  1308. else /* Return FALSE if op is undefined */
  1309. {
  1310. node-> result_type = TYPE_NUMBER;
  1311. node-> result_n = 0;
  1312. return 0;
  1313. }
  1314. }
  1315. else
  1316. if (the_operator == OP_DEFAULT)
  1317. {
  1318. copy_result (node, node-> op1);
  1319. return 0;
  1320. }
  1321. }
  1322. if (the_operator == OP_UNDEFINED)
  1323. node-> op2-> shuffle_in = node-> op1-> shuffle_out;
  1324. if (evaluate_script_node (node-> op2) != 0)
  1325. return -1;
  1326. node-> constant &= (node-> op2 ? node-> op2-> constant : TRUE);
  1327. if (node-> op2)
  1328. {
  1329. if (node-> op2-> result_type == TYPE_UNDEFINED)
  1330. {
  1331. if (! safe)
  1332. {
  1333. node-> culprit = node-> op2-> culprit;
  1334. return 0;
  1335. }
  1336. else /* Return FALSE if operand is undefined */
  1337. {
  1338. node-> result_type = TYPE_NUMBER;
  1339. node-> result_n = 0;
  1340. return 0;
  1341. }
  1342. }
  1343. }
  1344. else /* This should never happen, but might save us */
  1345. return 0;
  1346. /* Change safe operator to non-safe equevalent */
  1347. if (the_operator == OP_SAFE_EQUALS)
  1348. the_operator = OP_EQUALS;
  1349. else if (the_operator == OP_SAFE_NOT_EQUALS)
  1350. the_operator = OP_NOT_EQUALS;
  1351. else if (the_operator == OP_SAFE_GREATER_THAN)
  1352. the_operator = OP_GREATER_THAN;
  1353. else if (the_operator == OP_SAFE_LESS_THAN)
  1354. the_operator = OP_LESS_THAN;
  1355. else if (the_operator == OP_SAFE_GREATER_EQUAL)
  1356. the_operator = OP_GREATER_EQUAL;
  1357. else if (the_operator == OP_SAFE_LESS_EQUAL)
  1358. the_operator = OP_LESS_EQUAL;
  1359. if (node-> op1) /* Not unary operator */
  1360. number_result (node-> op1);
  1361. number_result (node-> op2);
  1362. /* If operator wants numeric operands, do conversion */
  1363. if ((the_operator == OP_TIMES)
  1364. || (the_operator == OP_DIVIDE)
  1365. || (the_operator == OP_PLUS)
  1366. || (the_operator == OP_MINUS)
  1367. || (the_operator == OP_OR)
  1368. || (the_operator == OP_AND)
  1369. || (the_operator == OP_NOT))
  1370. {
  1371. /* Binary PLUS between string operands or TIMES with string first */
  1372. /* operand are allowed. Otherwise both operands must be numeric. */
  1373. if ( (! ( ( (the_operator == OP_PLUS)
  1374. && (node-> op1) )
  1375. || ( (the_operator == OP_TIMES)
  1376. && (node-> op2-> result_type == TYPE_NUMBER) ) ))
  1377. && ((node-> op1 ? node-> op1-> result_type == TYPE_STRING : FALSE)
  1378. || (node-> op2-> result_type == TYPE_STRING)) )
  1379. {
  1380. gg_report_error ('E', "Non-numeric operand to numeric operator.");
  1381. return -1;
  1382. }
  1383. }
  1384. /* If the operator is UNDEFINED then we are concatenating strings, */
  1385. /* including the spaces, and shuffling if enabled. If the operator is */
  1386. /* PLUS and at least one of the operands is non-numeric then we also */
  1387. /* concatenate but do not include the spaces before the 2nd string. */
  1388. if (( the_operator == OP_UNDEFINED)
  1389. || ((the_operator == OP_PLUS) && (node-> op1)
  1390. && ((node-> op1-> result_type == TYPE_STRING)
  1391. || (node-> op2-> result_type == TYPE_STRING)) ) )
  1392. {
  1393. node-> constant = FALSE; /* Need to re-evaluate for shuffle */
  1394. offset = strlen (string_result (node-> op1));
  1395. if (node-> op1-> line_break)
  1396. offset++;
  1397. length = offset
  1398. + node-> op2-> indent
  1399. + strlen (string_result (node-> op2));
  1400. node-> result_s = mem_alloc (length + 1);
  1401. ASSERT (node-> result_s);
  1402. if (node-> op1)
  1403. {
  1404. strcpy (node-> result_s, node-> op1-> result_s);
  1405. if (node-> op1-> line_break)
  1406. strcat (node-> result_s, "\n");
  1407. }
  1408. if (the_operator == OP_UNDEFINED)
  1409. {
  1410. memset (node-> result_s + offset, ' ', node-> op2-> indent);
  1411. offset += node-> op2-> indent;
  1412. }
  1413. strcpy (node-> result_s + offset, node-> op2-> result_s);
  1414. node-> result_type = TYPE_STRING;
  1415. return 0;
  1416. }
  1417. /* "string" * 3 = "stringstringstring" */
  1418. if ((the_operator == OP_TIMES)
  1419. && (node-> op1-> result_type == TYPE_STRING)
  1420. && (node-> op2-> result_type == TYPE_NUMBER))
  1421. {
  1422. length = strlen (node-> op1-> result_s);
  1423. i = (long) node-> op2-> result_n; /* Integer value */
  1424. if (i < 0)
  1425. {
  1426. gg_report_error ('E', "String repeat count is negative.");
  1427. return -1;
  1428. }
  1429. node-> result_s = mem_alloc (length * i + 1);
  1430. ASSERT (node-> result_s);
  1431. offset = 0;
  1432. while (i-- > 0)
  1433. {
  1434. memcpy (node-> result_s + offset, node-> op1-> result_s, length);
  1435. offset += length;
  1436. }
  1437. node-> result_s [offset] = '\0';
  1438. node-> result_type = TYPE_STRING;
  1439. return 0;
  1440. }
  1441. /* If at least one operand is non-numeric, treat as a string operator */
  1442. if (node-> op1)
  1443. if ((node-> op1-> result_type == TYPE_STRING)
  1444. || (node-> op2-> result_type == TYPE_STRING))
  1445. {
  1446. cmp = strcmp (string_result (node-> op1),
  1447. string_result (node-> op2));
  1448. switch (the_operator)
  1449. {
  1450. case OP_EQUALS : n = (cmp == 0); break;
  1451. case OP_NOT_EQUALS : n = (cmp != 0); break;
  1452. case OP_GREATER_THAN : n = (cmp > 0); break;
  1453. case OP_LESS_THAN : n = (cmp < 0); break;
  1454. case OP_GREATER_EQUAL : n = (cmp >= 0); break;
  1455. case OP_LESS_EQUAL : n = (cmp <= 0); break;
  1456. default : gg_report_error ('E', "Invalid operator.");
  1457. return -1;
  1458. }
  1459. node-> result_type = TYPE_NUMBER;
  1460. node-> result_n = n;
  1461. return 0;
  1462. }
  1463. /* If we got here then we have two numeric operands. The operator may */
  1464. /* be unary, in which case the first operand is zero. */
  1465. switch (the_operator)
  1466. {
  1467. case OP_NOT : n = (double) (! (Bool) node-> op2-> result_n);
  1468. break;
  1469. case OP_PLUS : n = (node-> op1 ? node-> op1-> result_n : 0)
  1470. + node-> op2-> result_n; break;
  1471. case OP_MINUS : n = (node-> op1 ? node-> op1-> result_n : 0)
  1472. - node-> op2-> result_n; break;
  1473. case OP_TIMES : n = node-> op1-> result_n
  1474. * node-> op2-> result_n; break;
  1475. case OP_DIVIDE : if (node-> op2-> result_n != 0)
  1476. {
  1477. n = node-> op1-> result_n
  1478. / node-> op2-> result_n;
  1479. break;
  1480. }
  1481. else
  1482. {
  1483. gg_report_error ('E', "Division by zero.");
  1484. return -1;
  1485. }
  1486. case OP_EQUALS : n = (double) (node-> op1-> result_n
  1487. == node-> op2-> result_n); break;
  1488. case OP_NOT_EQUALS : n = (double) (node-> op1-> result_n
  1489. != node-> op2-> result_n); break;
  1490. case OP_GREATER_THAN : n = (double) (node-> op1-> result_n
  1491. > node-> op2-> result_n); break;
  1492. case OP_LESS_THAN : n = (double) (node-> op1-> result_n
  1493. < node-> op2-> result_n); break;
  1494. case OP_GREATER_EQUAL : n = (double) (node-> op1-> result_n
  1495. >= node-> op2-> result_n); break;