You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

213 lines
6.7 KiB

1 month ago
  1. % Copyright (C) 2001-2023 Artifex Software, Inc.
  2. % All Rights Reserved.
  3. %
  4. % This software is provided AS-IS with no warranty, either express or
  5. % implied.
  6. %
  7. % This software is distributed under license and may not be copied,
  8. % modified or distributed except as expressly authorized under the terms
  9. % of the license contained in the file LICENSE in this distribution.
  10. %
  11. % Refer to licensing information at http://www.artifex.com or contact
  12. % Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
  13. % CA 94129, USA, for further information.
  14. %
  15. % Initialization file for %disk device modifications
  16. % When this is run, systemdict is still writable,
  17. systemdict begin
  18. % Collect the list of searchable IODevices in SearchOrder
  19. % Efficiency here doesn't matter since we run this at the end
  20. % of gs_init and convert it to a static array.
  21. /.getsearchabledevs { % - .getsearchabledevs [ list_of_strings ]
  22. //systemdict /.searchabledevs .knownget not {
  23. .currentglobal //true .setglobal
  24. mark (*) {
  25. dup length string copy dup currentdevparams /Searchable
  26. .knownget { not { pop } if } { pop } ifelse
  27. } 8192 string /IODevice resourceforall
  28. ]
  29. % now process the array into correct SearchOrder
  30. 0 1 2 {
  31. mark exch 2 index {
  32. dup currentdevparams /SearchOrder get 2 index eq
  33. { exch } { pop } ifelse
  34. } forall % devices on the old list
  35. pop
  36. % make the array and sort it by name
  37. ] { lt } bind .sort
  38. exch
  39. } for
  40. % collect all devices with SearchOrder > 2
  41. mark 2 index {
  42. dup currentdevparams /SearchOrder get 2 gt
  43. { exch } { pop } ifelse
  44. } forall
  45. ] exch pop
  46. % We now have 4 arrays on the stack, SO=0 SO=1 SO=2 SO>2
  47. % make them into a single array
  48. mark 5 1 roll ] mark exch { { } forall } forall ]
  49. //systemdict /.searchabledevs 2 index .forceput
  50. exch .setglobal
  51. } executeonly
  52. if
  53. } .forcebind odef % must be bound and hidden for .forceput
  54. % Modify .putdevparams to force regeneration of .searchabledevs list
  55. /.putdevparams {
  56. % We could be smarter and check for %disk* device, but this
  57. % doesn't get run enough to justify the complication
  58. //.putdevparams
  59. //systemdict /.searchabledevs .forceundef
  60. } .forcebind odef % must be bound and hidden for .forceundef
  61. % ------ extend filenameforall to handle wildcards in %dev% part of pattern -------%
  62. /filenameforall {
  63. count 3 ge {
  64. 2 index (%) search {
  65. pop pop
  66. } {
  67. % no device specified, so search them all
  68. pop (*%) 3 index concatstrings
  69. % we need to suppress the device when we return the string
  70. % in order to match Adobe's behaviour with %disk devices.
  71. 4 -2 roll % the callers procedure
  72. [ { (%) search { pop pop (%) search { pop pop } if } if } /exec load
  73. 4 -1 roll % the callers procedure
  74. /exec load
  75. ] cvx
  76. 4 2 roll % put the modified procedure where it belongs
  77. } ifelse
  78. % extract device portion (up to end of string or next %)
  79. (%) search { exch pop } if % stack: opat proc scratch npat device
  80. dup (*) search { pop pop pop //true } { pop //false } ifelse
  81. 1 index (?) search { pop pop pop //true } { pop //false } ifelse
  82. or not {
  83. pop pop //filenameforall % device with no wildcard
  84. } {
  85. (%) concatstrings (%) exch concatstrings
  86. .getsearchabledevs
  87. % find all matching devices and add the rest of the search string
  88. mark exch {
  89. dup counttomark 1 add index .stringmatch {
  90. counttomark 2 add index concatstrings
  91. } {
  92. pop
  93. } ifelse
  94. } forall
  95. ]
  96. 3 1 roll pop pop
  97. 4 -1 roll pop
  98. % now we need to invoke filenameforall for each of the strings
  99. % in the array. We do this by building a procedure that is like
  100. % an unrolled 'forall' loop. We do this to get the parameters
  101. % for each filenameforall, since each execution will pop its
  102. % parameters, but we can't use the operand stack for storage
  103. % since each invocation must have the same operand stack.
  104. mark exch {
  105. counttomark dup 3 add index exch
  106. 2 add index
  107. /filenameforall load
  108. } forall
  109. ] cvx
  110. 3 1 roll pop pop
  111. exec % run our unrolled loop
  112. }
  113. ifelse
  114. } {
  115. //filenameforall % not enough parameters -- just let it fail
  116. }
  117. ifelse
  118. } odef
  119. % redefine file to search all devices in order
  120. /file {
  121. dup 0 get (r) 0 get eq dup {
  122. pop //false % success code
  123. 2 index 0 get 37 eq { [ () ] } { .getsearchabledevs } ifelse
  124. { 3 index concatstrings % prepend the device
  125. {
  126. 2 index //file } //.internalstopped exec not {
  127. 4 1 roll pop pop pop //true
  128. exit % exit with success
  129. } {
  130. pop pop
  131. }
  132. ifelse
  133. }
  134. forall
  135. }
  136. if
  137. not { % just let standard file operator handle things
  138. //file
  139. }
  140. if
  141. } .internalbind odef
  142. % redefine deletefile to search all devices in order
  143. /deletefile {
  144. //false % success code
  145. 1 index 0 get 37 eq { [ () ] } { .getsearchabledevs } ifelse
  146. { 2 index concatstrings % prepend the device
  147. { //deletefile } //.internalstopped exec exch pop not {
  148. pop //true exit % exit with success
  149. }
  150. if
  151. }
  152. forall
  153. not { $error /errorname get /deletefile .systemvar exch signalerror } if
  154. } .internalbind odef
  155. % redefine status to search all devices in order
  156. /status {
  157. dup type /stringtype eq {
  158. //false % success code
  159. 1 index 0 get 37 eq { [ () ] } { .getsearchabledevs } ifelse
  160. { 2 index concatstrings % prepend the device
  161. { //status } //.internalstopped exec not {
  162. { //true 7 -2 roll pop pop //true exit } % exit with success
  163. if
  164. }
  165. if
  166. }
  167. forall
  168. % If we made it this far, no devices were found to status the file
  169. % clean up to return 'false'
  170. exch pop
  171. } {
  172. //status
  173. }
  174. ifelse
  175. } .internalbind odef
  176. % Also redefine renamefile to search all devices in order
  177. /renamefile {
  178. //false % success code
  179. 2 index 0 get 37 eq { [ () ] } { .getsearchabledevs } ifelse
  180. { dup 4 index concatstrings % prepend the device
  181. { (r) //file } //.internalstopped exec
  182. not {
  183. closefile exch pop //true exit % exit with success
  184. } {
  185. pop pop
  186. } ifelse
  187. }
  188. forall
  189. not { $error /errorname get /renamefile .systemvar exch signalerror } if
  190. 3 -1 roll concatstrings exch
  191. //renamefile
  192. } .internalbind odef
  193. % redefine devforall to process devices in numeric order
  194. % Spec's for 'devforall' are unclear, but font downloaders may expect this
  195. /devforall { % <proc> <scratch> devforall -
  196. [ { dup length string copy } 2 index //devforall ]
  197. % stack: proc scratch array_of_device_names
  198. { lt } .sort
  199. % We don't really invoke the procedure with the scratch string
  200. % but rather with the strings from our array
  201. exch pop exch forall
  202. } odef
  203. end % systemdict