zmisc3.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
  2. This software is provided AS-IS with no warranty, either express or
  3. implied.
  4. This software is distributed under license and may not be copied,
  5. modified or distributed except as expressly authorized under the terms
  6. of the license contained in the file LICENSE in this distribution.
  7. For more information about licensing, please refer to
  8. http://www.ghostscript.com/licensing/. For information on
  9. commercial licensing, go to http://www.artifex.com/licensing/ or
  10. contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. San Rafael, CA 94903, U.S.A., +1(415)492-9861.
  12. */
  13. /* $Id: zmisc3.c,v 1.6 2004/08/04 19:36:13 stefan Exp $ */
  14. /* Miscellaneous LanguageLevel 3 operators */
  15. #include "ghost.h"
  16. #include "gscspace.h" /* for gscolor2.h */
  17. #include "gsmatrix.h" /* ditto */
  18. #include "gsclipsr.h"
  19. #include "gscolor2.h"
  20. #include "oper.h"
  21. #include "igstate.h"
  22. #include "store.h"
  23. /* - clipsave - */
  24. private int
  25. zclipsave(i_ctx_t *i_ctx_p)
  26. {
  27. return gs_clipsave(igs);
  28. }
  29. /* - cliprestore - */
  30. private int
  31. zcliprestore(i_ctx_t *i_ctx_p)
  32. {
  33. return gs_cliprestore(igs);
  34. }
  35. /* <proc1> <proc2> .eqproc <bool> */
  36. /*
  37. * Test whether two procedures are equal to depth 10.
  38. * This is the equality test used by idiom recognition in 'bind'.
  39. */
  40. #define MAX_DEPTH 10 /* depth is per Adobe specification */
  41. typedef struct ref2_s {
  42. ref proc1, proc2;
  43. } ref2_t;
  44. private int
  45. zeqproc(i_ctx_t *i_ctx_p)
  46. {
  47. os_ptr op = osp;
  48. ref2_t stack[MAX_DEPTH + 1];
  49. ref2_t *top = stack;
  50. make_array(&stack[0].proc1, 0, 1, op - 1);
  51. make_array(&stack[0].proc2, 0, 1, op);
  52. for (;;) {
  53. long i;
  54. if (r_size(&top->proc1) == 0) {
  55. /* Finished these arrays, go up to next level. */
  56. if (top == stack) {
  57. /* We're done matching: it succeeded. */
  58. make_true(op - 1);
  59. pop(1);
  60. return 0;
  61. }
  62. --top;
  63. continue;
  64. }
  65. /* Look at the next elements of the arrays. */
  66. i = r_size(&top->proc1) - 1;
  67. array_get(imemory, &top->proc1, i, &top[1].proc1);
  68. array_get(imemory, &top->proc2, i, &top[1].proc2);
  69. r_dec_size(&top->proc1, 1);
  70. ++top;
  71. /*
  72. * Amazingly enough, the objects' executable attributes are not
  73. * required to match. This means { x load } will match { /x load },
  74. * even though this is clearly wrong.
  75. */
  76. #if 0
  77. if (r_has_attr(&top->proc1, a_executable) !=
  78. r_has_attr(&top->proc2, a_executable)
  79. )
  80. break;
  81. #endif
  82. if (obj_eq(imemory, &top->proc1, &top->proc2)) {
  83. /* Names don't match strings. */
  84. if (r_type(&top->proc1) != r_type(&top->proc2) &&
  85. (r_type(&top->proc1) == t_name ||
  86. r_type(&top->proc2) == t_name)
  87. )
  88. break;
  89. --top; /* no recursion */
  90. continue;
  91. }
  92. if (r_is_array(&top->proc1) && r_is_array(&top->proc2) &&
  93. r_size(&top->proc1) == r_size(&top->proc2) &&
  94. top < stack + (MAX_DEPTH - 1)
  95. ) {
  96. /* Descend into the arrays. */
  97. continue;
  98. }
  99. break;
  100. }
  101. /* An exit from the loop indicates that matching failed. */
  102. make_false(op - 1);
  103. pop(1);
  104. return 0;
  105. }
  106. /* ------ Initialization procedure ------ */
  107. const op_def zmisc3_op_defs[] =
  108. {
  109. op_def_begin_ll3(),
  110. {"0cliprestore", zcliprestore},
  111. {"0clipsave", zclipsave},
  112. {"2.eqproc", zeqproc},
  113. op_def_end(0)
  114. };