laag-nasm 2.13.03.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (455) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +57 -0
  3. data/LICENSE.txt +29 -0
  4. data/README.org +34 -0
  5. data/ext/laag/nasm/extconf.rb +16 -0
  6. data/laag-nasm.gemspec +20 -0
  7. data/lib/laag/nasm.rb +29 -0
  8. data/patches/Makefile.in.patch +13 -0
  9. data/vendor/repo.or.cz/nasm/.gitignore +102 -0
  10. data/vendor/repo.or.cz/nasm/AUTHORS +137 -0
  11. data/vendor/repo.or.cz/nasm/CHANGES +2 -0
  12. data/vendor/repo.or.cz/nasm/ChangeLog +2905 -0
  13. data/vendor/repo.or.cz/nasm/INSTALL +102 -0
  14. data/vendor/repo.or.cz/nasm/LICENSE +29 -0
  15. data/vendor/repo.or.cz/nasm/Makefile.in +855 -0
  16. data/vendor/repo.or.cz/nasm/Mkfiles/README +46 -0
  17. data/vendor/repo.or.cz/nasm/Mkfiles/msvc.mak +732 -0
  18. data/vendor/repo.or.cz/nasm/Mkfiles/openwcom.mak +706 -0
  19. data/vendor/repo.or.cz/nasm/README +23 -0
  20. data/vendor/repo.or.cz/nasm/SubmittingPatches +116 -0
  21. data/vendor/repo.or.cz/nasm/TODO +376 -0
  22. data/vendor/repo.or.cz/nasm/aclocal.m4 +139 -0
  23. data/vendor/repo.or.cz/nasm/asm/assemble.c +2957 -0
  24. data/vendor/repo.or.cz/nasm/asm/assemble.h +54 -0
  25. data/vendor/repo.or.cz/nasm/asm/directiv.c +566 -0
  26. data/vendor/repo.or.cz/nasm/asm/directiv.dat +92 -0
  27. data/vendor/repo.or.cz/nasm/asm/error.c +202 -0
  28. data/vendor/repo.or.cz/nasm/asm/eval.c +1014 -0
  29. data/vendor/repo.or.cz/nasm/asm/eval.h +49 -0
  30. data/vendor/repo.or.cz/nasm/asm/exprdump.c +79 -0
  31. data/vendor/repo.or.cz/nasm/asm/exprlib.c +200 -0
  32. data/vendor/repo.or.cz/nasm/asm/float.c +952 -0
  33. data/vendor/repo.or.cz/nasm/asm/float.h +54 -0
  34. data/vendor/repo.or.cz/nasm/asm/labels.c +540 -0
  35. data/vendor/repo.or.cz/nasm/asm/listing.c +346 -0
  36. data/vendor/repo.or.cz/nasm/asm/listing.h +113 -0
  37. data/vendor/repo.or.cz/nasm/asm/nasm.c +1855 -0
  38. data/vendor/repo.or.cz/nasm/asm/parser.c +1167 -0
  39. data/vendor/repo.or.cz/nasm/asm/parser.h +45 -0
  40. data/vendor/repo.or.cz/nasm/asm/phash.pl +109 -0
  41. data/vendor/repo.or.cz/nasm/asm/pptok.dat +96 -0
  42. data/vendor/repo.or.cz/nasm/asm/pptok.pl +271 -0
  43. data/vendor/repo.or.cz/nasm/asm/pragma.c +218 -0
  44. data/vendor/repo.or.cz/nasm/asm/preproc-nop.c +188 -0
  45. data/vendor/repo.or.cz/nasm/asm/preproc.c +5459 -0
  46. data/vendor/repo.or.cz/nasm/asm/preproc.h +55 -0
  47. data/vendor/repo.or.cz/nasm/asm/quote.c +479 -0
  48. data/vendor/repo.or.cz/nasm/asm/quote.h +44 -0
  49. data/vendor/repo.or.cz/nasm/asm/rdstrnum.c +68 -0
  50. data/vendor/repo.or.cz/nasm/asm/segalloc.c +51 -0
  51. data/vendor/repo.or.cz/nasm/asm/stdscan.c +345 -0
  52. data/vendor/repo.or.cz/nasm/asm/stdscan.h +49 -0
  53. data/vendor/repo.or.cz/nasm/asm/strfunc.c +359 -0
  54. data/vendor/repo.or.cz/nasm/asm/tokens.dat +135 -0
  55. data/vendor/repo.or.cz/nasm/asm/tokhash.pl +284 -0
  56. data/vendor/repo.or.cz/nasm/autogen.sh +9 -0
  57. data/vendor/repo.or.cz/nasm/common/common.c +122 -0
  58. data/vendor/repo.or.cz/nasm/config/msvc.h +192 -0
  59. data/vendor/repo.or.cz/nasm/config/unknown.h +51 -0
  60. data/vendor/repo.or.cz/nasm/config/watcom.h +74 -0
  61. data/vendor/repo.or.cz/nasm/configure.ac +253 -0
  62. data/vendor/repo.or.cz/nasm/contrib/MSVC6.txt +25 -0
  63. data/vendor/repo.or.cz/nasm/contrib/VSrules/nasm.README +16 -0
  64. data/vendor/repo.or.cz/nasm/contrib/VSrules/nasm.rules +79 -0
  65. data/vendor/repo.or.cz/nasm/disasm/disasm.c +1735 -0
  66. data/vendor/repo.or.cz/nasm/disasm/disasm.h +49 -0
  67. data/vendor/repo.or.cz/nasm/disasm/ndisasm.c +397 -0
  68. data/vendor/repo.or.cz/nasm/disasm/sync.c +132 -0
  69. data/vendor/repo.or.cz/nasm/disasm/sync.h +45 -0
  70. data/vendor/repo.or.cz/nasm/doc/Makefile.in +86 -0
  71. data/vendor/repo.or.cz/nasm/doc/README +20 -0
  72. data/vendor/repo.or.cz/nasm/doc/afmmetrics.ph +102 -0
  73. data/vendor/repo.or.cz/nasm/doc/changes.src +2588 -0
  74. data/vendor/repo.or.cz/nasm/doc/findfont.ph +180 -0
  75. data/vendor/repo.or.cz/nasm/doc/genps.pl +1294 -0
  76. data/vendor/repo.or.cz/nasm/doc/inslist.pl +108 -0
  77. data/vendor/repo.or.cz/nasm/doc/internal.doc +290 -0
  78. data/vendor/repo.or.cz/nasm/doc/local.css +1 -0
  79. data/vendor/repo.or.cz/nasm/doc/nasmdoc.css +150 -0
  80. data/vendor/repo.or.cz/nasm/doc/nasmdoc.src +8309 -0
  81. data/vendor/repo.or.cz/nasm/doc/nasmlogo.eps +212 -0
  82. data/vendor/repo.or.cz/nasm/doc/nasmlogw.png +0 -0
  83. data/vendor/repo.or.cz/nasm/doc/psfonts.ph +53 -0
  84. data/vendor/repo.or.cz/nasm/doc/pspdf.pl +98 -0
  85. data/vendor/repo.or.cz/nasm/doc/pswidth.ph +25 -0
  86. data/vendor/repo.or.cz/nasm/doc/rdsrc.pl +1111 -0
  87. data/vendor/repo.or.cz/nasm/doc/ttfmetrics.ph +63 -0
  88. data/vendor/repo.or.cz/nasm/headers/c +33 -0
  89. data/vendor/repo.or.cz/nasm/headers/doc +33 -0
  90. data/vendor/repo.or.cz/nasm/headers/mac +33 -0
  91. data/vendor/repo.or.cz/nasm/headers/perl +33 -0
  92. data/vendor/repo.or.cz/nasm/include/compiler.h +277 -0
  93. data/vendor/repo.or.cz/nasm/include/disp8.h +45 -0
  94. data/vendor/repo.or.cz/nasm/include/error.h +135 -0
  95. data/vendor/repo.or.cz/nasm/include/hashtbl.h +85 -0
  96. data/vendor/repo.or.cz/nasm/include/iflag.h +173 -0
  97. data/vendor/repo.or.cz/nasm/include/insns.h +76 -0
  98. data/vendor/repo.or.cz/nasm/include/labels.h +60 -0
  99. data/vendor/repo.or.cz/nasm/include/md5.h +21 -0
  100. data/vendor/repo.or.cz/nasm/include/nasm.h +1246 -0
  101. data/vendor/repo.or.cz/nasm/include/nasmint.h +219 -0
  102. data/vendor/repo.or.cz/nasm/include/nasmlib.h +524 -0
  103. data/vendor/repo.or.cz/nasm/include/opflags.h +271 -0
  104. data/vendor/repo.or.cz/nasm/include/perfhash.h +52 -0
  105. data/vendor/repo.or.cz/nasm/include/raa.h +46 -0
  106. data/vendor/repo.or.cz/nasm/include/rbtree.h +51 -0
  107. data/vendor/repo.or.cz/nasm/include/rdoff.h +169 -0
  108. data/vendor/repo.or.cz/nasm/include/saa.h +94 -0
  109. data/vendor/repo.or.cz/nasm/include/strlist.h +55 -0
  110. data/vendor/repo.or.cz/nasm/include/tables.h +70 -0
  111. data/vendor/repo.or.cz/nasm/include/ver.h +47 -0
  112. data/vendor/repo.or.cz/nasm/install-sh +250 -0
  113. data/vendor/repo.or.cz/nasm/macros/altreg.mac +107 -0
  114. data/vendor/repo.or.cz/nasm/macros/fp.mac +54 -0
  115. data/vendor/repo.or.cz/nasm/macros/ifunc.mac +48 -0
  116. data/vendor/repo.or.cz/nasm/macros/macros.pl +294 -0
  117. data/vendor/repo.or.cz/nasm/macros/smartalign.mac +189 -0
  118. data/vendor/repo.or.cz/nasm/macros/standard.mac +226 -0
  119. data/vendor/repo.or.cz/nasm/misc/Doxyfile +752 -0
  120. data/vendor/repo.or.cz/nasm/misc/Nindent +18 -0
  121. data/vendor/repo.or.cz/nasm/misc/README +2 -0
  122. data/vendor/repo.or.cz/nasm/misc/c16.mac +82 -0
  123. data/vendor/repo.or.cz/nasm/misc/c32.mac +52 -0
  124. data/vendor/repo.or.cz/nasm/misc/crcgen.c +44 -0
  125. data/vendor/repo.or.cz/nasm/misc/exebin.mac +57 -0
  126. data/vendor/repo.or.cz/nasm/misc/exebin2.mac +114 -0
  127. data/vendor/repo.or.cz/nasm/misc/fmtinsns.pl +40 -0
  128. data/vendor/repo.or.cz/nasm/misc/genfma.pl +63 -0
  129. data/vendor/repo.or.cz/nasm/misc/hints.txt +26 -0
  130. data/vendor/repo.or.cz/nasm/misc/magic +6 -0
  131. data/vendor/repo.or.cz/nasm/misc/myC32.mac +121 -0
  132. data/vendor/repo.or.cz/nasm/misc/nasm.sl +320 -0
  133. data/vendor/repo.or.cz/nasm/misc/nasmstab +296 -0
  134. data/vendor/repo.or.cz/nasm/misc/omfdump.c +517 -0
  135. data/vendor/repo.or.cz/nasm/misc/pmw.bat +9 -0
  136. data/vendor/repo.or.cz/nasm/misc/proc32.ash +441 -0
  137. data/vendor/repo.or.cz/nasm/misc/scitech.mac +1223 -0
  138. data/vendor/repo.or.cz/nasm/misc/xcrcgen.c +80 -0
  139. data/vendor/repo.or.cz/nasm/nasm.spec.in +83 -0
  140. data/vendor/repo.or.cz/nasm/nasm.spec.sed +3 -0
  141. data/vendor/repo.or.cz/nasm/nasm.txt +306 -0
  142. data/vendor/repo.or.cz/nasm/nasmlib/badenum.c +43 -0
  143. data/vendor/repo.or.cz/nasm/nasmlib/bsi.c +77 -0
  144. data/vendor/repo.or.cz/nasm/nasmlib/crc64.c +189 -0
  145. data/vendor/repo.or.cz/nasm/nasmlib/file.c +259 -0
  146. data/vendor/repo.or.cz/nasm/nasmlib/file.h +128 -0
  147. data/vendor/repo.or.cz/nasm/nasmlib/filename.c +69 -0
  148. data/vendor/repo.or.cz/nasm/nasmlib/hashtbl.c +232 -0
  149. data/vendor/repo.or.cz/nasm/nasmlib/ilog2.c +168 -0
  150. data/vendor/repo.or.cz/nasm/nasmlib/malloc.c +108 -0
  151. data/vendor/repo.or.cz/nasm/nasmlib/md5c.c +247 -0
  152. data/vendor/repo.or.cz/nasm/nasmlib/mmap.c +139 -0
  153. data/vendor/repo.or.cz/nasm/nasmlib/path.c +186 -0
  154. data/vendor/repo.or.cz/nasm/nasmlib/perfhash.c +55 -0
  155. data/vendor/repo.or.cz/nasm/nasmlib/perfhash.pl +362 -0
  156. data/vendor/repo.or.cz/nasm/nasmlib/raa.c +173 -0
  157. data/vendor/repo.or.cz/nasm/nasmlib/rbtree.c +119 -0
  158. data/vendor/repo.or.cz/nasm/nasmlib/readnum.c +172 -0
  159. data/vendor/repo.or.cz/nasm/nasmlib/realpath.c +135 -0
  160. data/vendor/repo.or.cz/nasm/nasmlib/saa.c +431 -0
  161. data/vendor/repo.or.cz/nasm/nasmlib/srcfile.c +128 -0
  162. data/vendor/repo.or.cz/nasm/nasmlib/string.c +242 -0
  163. data/vendor/repo.or.cz/nasm/nasmlib/strlist.c +100 -0
  164. data/vendor/repo.or.cz/nasm/nasmlib/ver.c +51 -0
  165. data/vendor/repo.or.cz/nasm/nasmlib/zerobuf.c +42 -0
  166. data/vendor/repo.or.cz/nasm/ndisasm.txt +94 -0
  167. data/vendor/repo.or.cz/nasm/nsis/NASMMultiUser.nsh +478 -0
  168. data/vendor/repo.or.cz/nasm/nsis/getpearch.pl +76 -0
  169. data/vendor/repo.or.cz/nasm/nsis/nasm-un.ico +0 -0
  170. data/vendor/repo.or.cz/nasm/nsis/nasm.ico +0 -0
  171. data/vendor/repo.or.cz/nasm/nsis/nasm.nsi +241 -0
  172. data/vendor/repo.or.cz/nasm/output/codeview.c +814 -0
  173. data/vendor/repo.or.cz/nasm/output/dwarf.h +566 -0
  174. data/vendor/repo.or.cz/nasm/output/elf.h +537 -0
  175. data/vendor/repo.or.cz/nasm/output/legacy.c +112 -0
  176. data/vendor/repo.or.cz/nasm/output/nulldbg.c +93 -0
  177. data/vendor/repo.or.cz/nasm/output/nullout.c +51 -0
  178. data/vendor/repo.or.cz/nasm/output/outaout.c +954 -0
  179. data/vendor/repo.or.cz/nasm/output/outaout.mac +37 -0
  180. data/vendor/repo.or.cz/nasm/output/outas86.c +650 -0
  181. data/vendor/repo.or.cz/nasm/output/outas86.mac +37 -0
  182. data/vendor/repo.or.cz/nasm/output/outbin.c +1713 -0
  183. data/vendor/repo.or.cz/nasm/output/outbin.mac +40 -0
  184. data/vendor/repo.or.cz/nasm/output/outcoff.c +1242 -0
  185. data/vendor/repo.or.cz/nasm/output/outcoff.mac +43 -0
  186. data/vendor/repo.or.cz/nasm/output/outdbg.c +425 -0
  187. data/vendor/repo.or.cz/nasm/output/outelf.c +3370 -0
  188. data/vendor/repo.or.cz/nasm/output/outelf.h +156 -0
  189. data/vendor/repo.or.cz/nasm/output/outelf.mac +41 -0
  190. data/vendor/repo.or.cz/nasm/output/outform.c +120 -0
  191. data/vendor/repo.or.cz/nasm/output/outform.h +379 -0
  192. data/vendor/repo.or.cz/nasm/output/outieee.c +1528 -0
  193. data/vendor/repo.or.cz/nasm/output/outlib.c +58 -0
  194. data/vendor/repo.or.cz/nasm/output/outlib.h +63 -0
  195. data/vendor/repo.or.cz/nasm/output/outmacho.c +2387 -0
  196. data/vendor/repo.or.cz/nasm/output/outmacho.mac +49 -0
  197. data/vendor/repo.or.cz/nasm/output/outobj.c +2725 -0
  198. data/vendor/repo.or.cz/nasm/output/outobj.mac +49 -0
  199. data/vendor/repo.or.cz/nasm/output/outrdf.mac +40 -0
  200. data/vendor/repo.or.cz/nasm/output/outrdf2.c +791 -0
  201. data/vendor/repo.or.cz/nasm/output/outrdf2.mac +43 -0
  202. data/vendor/repo.or.cz/nasm/output/pecoff.h +532 -0
  203. data/vendor/repo.or.cz/nasm/output/stabs.h +144 -0
  204. data/vendor/repo.or.cz/nasm/perllib/crc64.ph +158 -0
  205. data/vendor/repo.or.cz/nasm/perllib/gensv.pl +34 -0
  206. data/vendor/repo.or.cz/nasm/perllib/phash.ph +200 -0
  207. data/vendor/repo.or.cz/nasm/perllib/random_sv_vectors.ph +67 -0
  208. data/vendor/repo.or.cz/nasm/rdoff/README +185 -0
  209. data/vendor/repo.or.cz/nasm/rdoff/collectn.c +44 -0
  210. data/vendor/repo.or.cz/nasm/rdoff/collectn.h +22 -0
  211. data/vendor/repo.or.cz/nasm/rdoff/doc/Makefile +37 -0
  212. data/vendor/repo.or.cz/nasm/rdoff/doc/rdoff.texi +137 -0
  213. data/vendor/repo.or.cz/nasm/rdoff/doc/v1-v2.txt +62 -0
  214. data/vendor/repo.or.cz/nasm/rdoff/hash.c +122 -0
  215. data/vendor/repo.or.cz/nasm/rdoff/hash.h +17 -0
  216. data/vendor/repo.or.cz/nasm/rdoff/ldrdf.1 +41 -0
  217. data/vendor/repo.or.cz/nasm/rdoff/ldrdf.c +1395 -0
  218. data/vendor/repo.or.cz/nasm/rdoff/ldsegs.h +59 -0
  219. data/vendor/repo.or.cz/nasm/rdoff/rdf2bin.1 +65 -0
  220. data/vendor/repo.or.cz/nasm/rdoff/rdf2bin.c +431 -0
  221. data/vendor/repo.or.cz/nasm/rdoff/rdf2com.1 +1 -0
  222. data/vendor/repo.or.cz/nasm/rdoff/rdf2ihx.1 +1 -0
  223. data/vendor/repo.or.cz/nasm/rdoff/rdf2ith.1 +1 -0
  224. data/vendor/repo.or.cz/nasm/rdoff/rdf2srec.1 +1 -0
  225. data/vendor/repo.or.cz/nasm/rdoff/rdfdump.1 +24 -0
  226. data/vendor/repo.or.cz/nasm/rdoff/rdfdump.c +347 -0
  227. data/vendor/repo.or.cz/nasm/rdoff/rdflib.1 +39 -0
  228. data/vendor/repo.or.cz/nasm/rdoff/rdflib.c +434 -0
  229. data/vendor/repo.or.cz/nasm/rdoff/rdfload.c +213 -0
  230. data/vendor/repo.or.cz/nasm/rdoff/rdfload.h +29 -0
  231. data/vendor/repo.or.cz/nasm/rdoff/rdfutils.h +165 -0
  232. data/vendor/repo.or.cz/nasm/rdoff/rdlar.c +492 -0
  233. data/vendor/repo.or.cz/nasm/rdoff/rdlar.h +34 -0
  234. data/vendor/repo.or.cz/nasm/rdoff/rdlib.c +290 -0
  235. data/vendor/repo.or.cz/nasm/rdoff/rdlib.h +62 -0
  236. data/vendor/repo.or.cz/nasm/rdoff/rdoff.c +621 -0
  237. data/vendor/repo.or.cz/nasm/rdoff/rdx.1 +21 -0
  238. data/vendor/repo.or.cz/nasm/rdoff/rdx.c +90 -0
  239. data/vendor/repo.or.cz/nasm/rdoff/segtab.c +172 -0
  240. data/vendor/repo.or.cz/nasm/rdoff/segtab.h +45 -0
  241. data/vendor/repo.or.cz/nasm/rdoff/symtab.c +159 -0
  242. data/vendor/repo.or.cz/nasm/rdoff/symtab.h +55 -0
  243. data/vendor/repo.or.cz/nasm/rdoff/test/Makefile +10 -0
  244. data/vendor/repo.or.cz/nasm/rdoff/test/makelib.sh +14 -0
  245. data/vendor/repo.or.cz/nasm/rdoff/test/rdfseg.asm +20 -0
  246. data/vendor/repo.or.cz/nasm/rdoff/test/rdfseg2.asm +12 -0
  247. data/vendor/repo.or.cz/nasm/rdoff/test/rdftest1.asm +54 -0
  248. data/vendor/repo.or.cz/nasm/rdoff/test/rdftest2.asm +33 -0
  249. data/vendor/repo.or.cz/nasm/rdoff/test/rdtlib.asm +48 -0
  250. data/vendor/repo.or.cz/nasm/rdoff/test/rdtmain.asm +47 -0
  251. data/vendor/repo.or.cz/nasm/rdoff/test/testlib.asm +18 -0
  252. data/vendor/repo.or.cz/nasm/stdlib/snprintf.c +29 -0
  253. data/vendor/repo.or.cz/nasm/stdlib/strlcpy.c +51 -0
  254. data/vendor/repo.or.cz/nasm/stdlib/strnlen.c +46 -0
  255. data/vendor/repo.or.cz/nasm/stdlib/vsnprintf.c +51 -0
  256. data/vendor/repo.or.cz/nasm/test/Makefile +106 -0
  257. data/vendor/repo.or.cz/nasm/test/_file_.asm +5 -0
  258. data/vendor/repo.or.cz/nasm/test/_version.asm +2 -0
  259. data/vendor/repo.or.cz/nasm/test/a32offs.asm +9 -0
  260. data/vendor/repo.or.cz/nasm/test/absolute.asm +40 -0
  261. data/vendor/repo.or.cz/nasm/test/addr64x.asm +18 -0
  262. data/vendor/repo.or.cz/nasm/test/align13.asm +19 -0
  263. data/vendor/repo.or.cz/nasm/test/align13s.asm +20 -0
  264. data/vendor/repo.or.cz/nasm/test/alonesym-obj.asm +166 -0
  265. data/vendor/repo.or.cz/nasm/test/andbyte.asm +15 -0
  266. data/vendor/repo.or.cz/nasm/test/aoutso.asm +99 -0
  267. data/vendor/repo.or.cz/nasm/test/aouttest.asm +86 -0
  268. data/vendor/repo.or.cz/nasm/test/aouttest.c +36 -0
  269. data/vendor/repo.or.cz/nasm/test/avx.asm +46 -0
  270. data/vendor/repo.or.cz/nasm/test/avx005.asm +529 -0
  271. data/vendor/repo.or.cz/nasm/test/avx2.asm +1608 -0
  272. data/vendor/repo.or.cz/nasm/test/avx512cd.asm +106 -0
  273. data/vendor/repo.or.cz/nasm/test/avx512er.asm +144 -0
  274. data/vendor/repo.or.cz/nasm/test/avx512f.asm +7000 -0
  275. data/vendor/repo.or.cz/nasm/test/avx512pf.asm +88 -0
  276. data/vendor/repo.or.cz/nasm/test/bcd.asm +23 -0
  277. data/vendor/repo.or.cz/nasm/test/binexe.asm +35 -0
  278. data/vendor/repo.or.cz/nasm/test/bintest.asm +59 -0
  279. data/vendor/repo.or.cz/nasm/test/bisect.sh +22 -0
  280. data/vendor/repo.or.cz/nasm/test/br1879590.asm +25 -0
  281. data/vendor/repo.or.cz/nasm/test/br2003451.asm +17 -0
  282. data/vendor/repo.or.cz/nasm/test/br2030823.asm +7 -0
  283. data/vendor/repo.or.cz/nasm/test/br2148476.asm +221 -0
  284. data/vendor/repo.or.cz/nasm/test/br2222615.asm +19 -0
  285. data/vendor/repo.or.cz/nasm/test/br2496848.asm +42 -0
  286. data/vendor/repo.or.cz/nasm/test/br3005117.asm +26 -0
  287. data/vendor/repo.or.cz/nasm/test/br3026808.asm +20 -0
  288. data/vendor/repo.or.cz/nasm/test/br3028880.asm +8 -0
  289. data/vendor/repo.or.cz/nasm/test/br3041451.asm +59 -0
  290. data/vendor/repo.or.cz/nasm/test/br3058845.asm +14 -0
  291. data/vendor/repo.or.cz/nasm/test/br3066383.asm +70 -0
  292. data/vendor/repo.or.cz/nasm/test/br3074517.asm +12 -0
  293. data/vendor/repo.or.cz/nasm/test/br3092924.asm +25 -0
  294. data/vendor/repo.or.cz/nasm/test/br3104312.asm +11 -0
  295. data/vendor/repo.or.cz/nasm/test/br3109604.asm +9 -0
  296. data/vendor/repo.or.cz/nasm/test/br3174983.asm +9 -0
  297. data/vendor/repo.or.cz/nasm/test/br3187743.asm +7 -0
  298. data/vendor/repo.or.cz/nasm/test/br3189064.asm +7 -0
  299. data/vendor/repo.or.cz/nasm/test/br3200749.asm +9 -0
  300. data/vendor/repo.or.cz/nasm/test/br3385573.asm +11 -0
  301. data/vendor/repo.or.cz/nasm/test/br3392252.asm +43 -0
  302. data/vendor/repo.or.cz/nasm/test/br3392259.asm +8 -0
  303. data/vendor/repo.or.cz/nasm/test/br3392363.asm +4 -0
  304. data/vendor/repo.or.cz/nasm/test/br3392392.asm +16 -0
  305. data/vendor/repo.or.cz/nasm/test/br3392396.asm +5 -0
  306. data/vendor/repo.or.cz/nasm/test/br3392411.asm +22 -0
  307. data/vendor/repo.or.cz/nasm/test/br3392418.asm +3 -0
  308. data/vendor/repo.or.cz/nasm/test/br3392439.asm +25 -0
  309. data/vendor/repo.or.cz/nasm/test/br3392442.asm +6 -0
  310. data/vendor/repo.or.cz/nasm/test/br560575.asm +17 -0
  311. data/vendor/repo.or.cz/nasm/test/br560873.asm +27 -0
  312. data/vendor/repo.or.cz/nasm/test/br890790.asm +7 -0
  313. data/vendor/repo.or.cz/nasm/test/br890790_i.asm +1 -0
  314. data/vendor/repo.or.cz/nasm/test/br978756.asm +7 -0
  315. data/vendor/repo.or.cz/nasm/test/changed.asm +383 -0
  316. data/vendor/repo.or.cz/nasm/test/cofftest.asm +85 -0
  317. data/vendor/repo.or.cz/nasm/test/cofftest.c +35 -0
  318. data/vendor/repo.or.cz/nasm/test/crc32.asm +37 -0
  319. data/vendor/repo.or.cz/nasm/test/cv8struc.asm +14 -0
  320. data/vendor/repo.or.cz/nasm/test/dtbcd.asm +72 -0
  321. data/vendor/repo.or.cz/nasm/test/elf64so.asm +118 -0
  322. data/vendor/repo.or.cz/nasm/test/elfso.asm +100 -0
  323. data/vendor/repo.or.cz/nasm/test/elftest.asm +87 -0
  324. data/vendor/repo.or.cz/nasm/test/elftest.c +38 -0
  325. data/vendor/repo.or.cz/nasm/test/elftest64.c +43 -0
  326. data/vendor/repo.or.cz/nasm/test/elif.asm +39 -0
  327. data/vendor/repo.or.cz/nasm/test/expimp.asm +90 -0
  328. data/vendor/repo.or.cz/nasm/test/far64.asm +10 -0
  329. data/vendor/repo.or.cz/nasm/test/float.asm +186 -0
  330. data/vendor/repo.or.cz/nasm/test/float8.asm +135 -0
  331. data/vendor/repo.or.cz/nasm/test/floatb.asm +35 -0
  332. data/vendor/repo.or.cz/nasm/test/floatexp.asm +382 -0
  333. data/vendor/repo.or.cz/nasm/test/floatize.asm +19 -0
  334. data/vendor/repo.or.cz/nasm/test/floattest.asm +28 -0
  335. data/vendor/repo.or.cz/nasm/test/floatx.asm +525 -0
  336. data/vendor/repo.or.cz/nasm/test/fpu.asm +127 -0
  337. data/vendor/repo.or.cz/nasm/test/fwdopt.asm +133 -0
  338. data/vendor/repo.or.cz/nasm/test/fwdoptpp.asm +150 -0
  339. data/vendor/repo.or.cz/nasm/test/gas2nasm.py +104 -0
  340. data/vendor/repo.or.cz/nasm/test/gather.asm +11 -0
  341. data/vendor/repo.or.cz/nasm/test/gotoff64.asm +25 -0
  342. data/vendor/repo.or.cz/nasm/test/hexfp.asm +25 -0
  343. data/vendor/repo.or.cz/nasm/test/hle.asm +19 -0
  344. data/vendor/repo.or.cz/nasm/test/ifelse.asm +46 -0
  345. data/vendor/repo.or.cz/nasm/test/ifenv.asm +31 -0
  346. data/vendor/repo.or.cz/nasm/test/ifmacro.asm +413 -0
  347. data/vendor/repo.or.cz/nasm/test/iftoken.asm +317 -0
  348. data/vendor/repo.or.cz/nasm/test/iftoken.pl +32 -0
  349. data/vendor/repo.or.cz/nasm/test/ilog2.asm +271 -0
  350. data/vendor/repo.or.cz/nasm/test/imacro.asm +8 -0
  351. data/vendor/repo.or.cz/nasm/test/imm.asm +23 -0
  352. data/vendor/repo.or.cz/nasm/test/imm64.asm +61 -0
  353. data/vendor/repo.or.cz/nasm/test/immwarn.asm +91 -0
  354. data/vendor/repo.or.cz/nasm/test/imul.asm +117 -0
  355. data/vendor/repo.or.cz/nasm/test/inc1.asm +6 -0
  356. data/vendor/repo.or.cz/nasm/test/inc2.asm +8 -0
  357. data/vendor/repo.or.cz/nasm/test/incbin.asm +7 -0
  358. data/vendor/repo.or.cz/nasm/test/incbin.data +2 -0
  359. data/vendor/repo.or.cz/nasm/test/inctest.asm +15 -0
  360. data/vendor/repo.or.cz/nasm/test/insnlbl.asm +12 -0
  361. data/vendor/repo.or.cz/nasm/test/invlpga.asm +11 -0
  362. data/vendor/repo.or.cz/nasm/test/jmp64.asm +19 -0
  363. data/vendor/repo.or.cz/nasm/test/lar_lsl.asm +124 -0
  364. data/vendor/repo.or.cz/nasm/test/larlsl.asm +23 -0
  365. data/vendor/repo.or.cz/nasm/test/lnxhello.asm +54 -0
  366. data/vendor/repo.or.cz/nasm/test/local.asm +19 -0
  367. data/vendor/repo.or.cz/nasm/test/loopoffs.asm +12 -0
  368. data/vendor/repo.or.cz/nasm/test/lwp.asm +213 -0
  369. data/vendor/repo.or.cz/nasm/test/macro-defaults.asm +64 -0
  370. data/vendor/repo.or.cz/nasm/test/macroerr.asm +12 -0
  371. data/vendor/repo.or.cz/nasm/test/macroerr.inc +3 -0
  372. data/vendor/repo.or.cz/nasm/test/mmxsize.asm +38 -0
  373. data/vendor/repo.or.cz/nasm/test/movd.asm +12 -0
  374. data/vendor/repo.or.cz/nasm/test/movd64.asm +15 -0
  375. data/vendor/repo.or.cz/nasm/test/movimm.asm +28 -0
  376. data/vendor/repo.or.cz/nasm/test/movnti.asm +10 -0
  377. data/vendor/repo.or.cz/nasm/test/mpx-64.asm +120 -0
  378. data/vendor/repo.or.cz/nasm/test/mpx.asm +89 -0
  379. data/vendor/repo.or.cz/nasm/test/multisection.asm +96 -0
  380. data/vendor/repo.or.cz/nasm/test/nasmformat.asm +17 -0
  381. data/vendor/repo.or.cz/nasm/test/new +9 -0
  382. data/vendor/repo.or.cz/nasm/test/newrdwr.asm +24 -0
  383. data/vendor/repo.or.cz/nasm/test/nop.asm +17 -0
  384. data/vendor/repo.or.cz/nasm/test/nullfile.asm +4 -0
  385. data/vendor/repo.or.cz/nasm/test/objexe.asm +30 -0
  386. data/vendor/repo.or.cz/nasm/test/objlink.c +33 -0
  387. data/vendor/repo.or.cz/nasm/test/objtest.asm +85 -0
  388. data/vendor/repo.or.cz/nasm/test/optimization.asm +104 -0
  389. data/vendor/repo.or.cz/nasm/test/org.asm +18 -0
  390. data/vendor/repo.or.cz/nasm/test/paste.asm +12 -0
  391. data/vendor/repo.or.cz/nasm/test/pcrel.asm +52 -0
  392. data/vendor/repo.or.cz/nasm/test/perf/label.pl +18 -0
  393. data/vendor/repo.or.cz/nasm/test/perf/macro.pl +18 -0
  394. data/vendor/repo.or.cz/nasm/test/perf/token.pl +23 -0
  395. data/vendor/repo.or.cz/nasm/test/performtest.pl +192 -0
  396. data/vendor/repo.or.cz/nasm/test/pextrw.asm +3 -0
  397. data/vendor/repo.or.cz/nasm/test/pinsr16.asm +53 -0
  398. data/vendor/repo.or.cz/nasm/test/pinsr32.asm +53 -0
  399. data/vendor/repo.or.cz/nasm/test/pinsr64.asm +68 -0
  400. data/vendor/repo.or.cz/nasm/test/popcnt.asm +32 -0
  401. data/vendor/repo.or.cz/nasm/test/ppindirect.asm +42 -0
  402. data/vendor/repo.or.cz/nasm/test/pragma.asm +12 -0
  403. data/vendor/repo.or.cz/nasm/test/prefix66.asm +28 -0
  404. data/vendor/repo.or.cz/nasm/test/ptr.asm +4 -0
  405. data/vendor/repo.or.cz/nasm/test/pushseg.asm +17 -0
  406. data/vendor/repo.or.cz/nasm/test/r13.asm +15 -0
  407. data/vendor/repo.or.cz/nasm/test/radix.asm +54 -0
  408. data/vendor/repo.or.cz/nasm/test/rdpid.asm +21 -0
  409. data/vendor/repo.or.cz/nasm/test/reldef.asm +57 -0
  410. data/vendor/repo.or.cz/nasm/test/relocs.asm +20 -0
  411. data/vendor/repo.or.cz/nasm/test/riprel.asm +5357 -0
  412. data/vendor/repo.or.cz/nasm/test/riprel.pl +29 -0
  413. data/vendor/repo.or.cz/nasm/test/riprel2.asm +11 -0
  414. data/vendor/repo.or.cz/nasm/test/sha-64.asm +30 -0
  415. data/vendor/repo.or.cz/nasm/test/sha.asm +31 -0
  416. data/vendor/repo.or.cz/nasm/test/smartalign16.asm +36 -0
  417. data/vendor/repo.or.cz/nasm/test/smartalign32.asm +36 -0
  418. data/vendor/repo.or.cz/nasm/test/smartalign64.asm +36 -0
  419. data/vendor/repo.or.cz/nasm/test/splitea.asm +11 -0
  420. data/vendor/repo.or.cz/nasm/test/sreg.asm +65 -0
  421. data/vendor/repo.or.cz/nasm/test/strlen.asm +5 -0
  422. data/vendor/repo.or.cz/nasm/test/struc.asm +33 -0
  423. data/vendor/repo.or.cz/nasm/test/test67.asm +38 -0
  424. data/vendor/repo.or.cz/nasm/test/testdos.asm +13 -0
  425. data/vendor/repo.or.cz/nasm/test/testnos3.asm +973 -0
  426. data/vendor/repo.or.cz/nasm/test/time.asm +11 -0
  427. data/vendor/repo.or.cz/nasm/test/times.asm +21 -0
  428. data/vendor/repo.or.cz/nasm/test/timesneg.asm +3 -0
  429. data/vendor/repo.or.cz/nasm/test/tmap.nas +1447 -0
  430. data/vendor/repo.or.cz/nasm/test/uscore.asm +15 -0
  431. data/vendor/repo.or.cz/nasm/test/utf.asm +82 -0
  432. data/vendor/repo.or.cz/nasm/test/vaesenc.asm +22 -0
  433. data/vendor/repo.or.cz/nasm/test/vex.asm +9 -0
  434. data/vendor/repo.or.cz/nasm/test/vgather.asm +76 -0
  435. data/vendor/repo.or.cz/nasm/test/vmread.asm +26 -0
  436. data/vendor/repo.or.cz/nasm/test/weirdpaste.asm +29 -0
  437. data/vendor/repo.or.cz/nasm/test/xchg.asm +96 -0
  438. data/vendor/repo.or.cz/nasm/test/xcrypt.asm +24 -0
  439. data/vendor/repo.or.cz/nasm/test/xmm0.asm +12 -0
  440. data/vendor/repo.or.cz/nasm/test/zerobyte.asm +22 -0
  441. data/vendor/repo.or.cz/nasm/tools/cleanfile +176 -0
  442. data/vendor/repo.or.cz/nasm/tools/cleanpatch +258 -0
  443. data/vendor/repo.or.cz/nasm/tools/mkdep.pl +261 -0
  444. data/vendor/repo.or.cz/nasm/tools/release +105 -0
  445. data/vendor/repo.or.cz/nasm/tools/syncfiles.pl +137 -0
  446. data/vendor/repo.or.cz/nasm/tools/tag-release +58 -0
  447. data/vendor/repo.or.cz/nasm/version +1 -0
  448. data/vendor/repo.or.cz/nasm/version.pl +189 -0
  449. data/vendor/repo.or.cz/nasm/x86/disp8.c +131 -0
  450. data/vendor/repo.or.cz/nasm/x86/insns-iflags.ph +280 -0
  451. data/vendor/repo.or.cz/nasm/x86/insns.dat +5371 -0
  452. data/vendor/repo.or.cz/nasm/x86/insns.pl +1043 -0
  453. data/vendor/repo.or.cz/nasm/x86/regs.dat +138 -0
  454. data/vendor/repo.or.cz/nasm/x86/regs.pl +204 -0
  455. metadata +520 -0
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/perl
2
+ ## --------------------------------------------------------------------------
3
+ ##
4
+ ## Copyright 1996-2017 The NASM Authors - All Rights Reserved
5
+ ## See the file AUTHORS included with the NASM distribution for
6
+ ## the specific copyright holders.
7
+ ##
8
+ ## Redistribution and use in source and binary forms, with or without
9
+ ## modification, are permitted provided that the following
10
+ ## conditions are met:
11
+ ##
12
+ ## * Redistributions of source code must retain the above copyright
13
+ ## notice, this list of conditions and the following disclaimer.
14
+ ## * Redistributions in binary form must reproduce the above
15
+ ## copyright notice, this list of conditions and the following
16
+ ## disclaimer in the documentation and/or other materials provided
17
+ ## with the distribution.
18
+ ##
19
+ ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
20
+ ## CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
21
+ ## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22
+ ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ ## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24
+ ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26
+ ## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27
+ ## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
+ ## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29
+ ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30
+ ## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
31
+ ## EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+ ##
33
+ ## --------------------------------------------------------------------------
34
+
35
+ #
36
+ # Try our best to find a specific PostScipt font in the system.
37
+ # We need to find the font files so we can extract the metrics.
38
+ # Sadly there isn't any reasonable Perl module to do this for us,
39
+ # as far as I can tell.
40
+ #
41
+
42
+ use strict;
43
+ use File::Spec;
44
+ use File::Find;
45
+
46
+ require 'afmmetrics.ph';
47
+ require 'ttfmetrics.ph';
48
+
49
+ my %font_info_hash = ();
50
+ my $fonts_scanned = 0;
51
+ my %prefs = { 'otf' => 1, 'ttf' => 2, 'pfa' => 3, 'pfb' => 4 };
52
+
53
+ sub add_file_to_font_hash($) {
54
+ my($filename) = @_;
55
+
56
+ return unless ( -f $filename );
57
+ return unless ( $filename =~ /^(.*)\.([[:alnum:]]+)$/ );
58
+
59
+ my $filestem = $1;
60
+ my $fonttype = $2;
61
+ my $fontdata;
62
+
63
+ if ( $filename =~ /\.(otf|ttf)$/i ) {
64
+ $fontdata = parse_ttf_file($filename);
65
+ } elsif ( $filename =~ /\.(pfa|pfb)$/i ) {
66
+ if ( -f "${filestem}.afm" ) {
67
+ $fontdata = parse_afm_file($filestem, $fonttype);
68
+ }
69
+ }
70
+
71
+ return unless (defined($fontdata));
72
+
73
+ my $oldinfo = $font_info_hash{$fontdata->{name}};
74
+
75
+ if (!defined($oldinfo) ||
76
+ $prefs{$fontdata->{type}} < $prefs{$oldinfo->{type}}) {
77
+ $font_info_hash{$fontdata->{name}} = $fontdata;
78
+ }
79
+ }
80
+
81
+ my $win32_ok = eval {
82
+ require Win32::TieRegistry;
83
+ Win32::TieRegistry->import();
84
+ 1;
85
+ };
86
+
87
+ # Based on Font::TTF::Win32 by
88
+ # Martin Hosken <http://scripts.sil.org/FontUtils>.
89
+ # LICENSING
90
+ #
91
+ # Copyright (c) 1998-2014, SIL International (http://www.sil.org)
92
+ #
93
+ # This module is released under the terms of the Artistic License 2.0.
94
+ # For details, see the full text of the license in the file LICENSE.
95
+ sub scanfonts_win32() {
96
+ return unless ($win32_ok);
97
+
98
+ my $Reg = $::Registry->Open('', {Access=>'KEY_READ', Delimiter=>'/'});
99
+ my $fd;
100
+ foreach my $win ('Windows NT', 'Windows') {
101
+ $fd = $Reg->{"HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/$win/CurrentVersion/Fonts"};
102
+ last if (defined($fd));
103
+ }
104
+ return unless (defined($fd));
105
+
106
+ foreach my $font (keys(%$fd)) {
107
+ my($fname, $ftype) = ($font =~ m:^/(.+?)(| \([^\(\)]+\))$:);
108
+ next unless ($ftype =~ / \((TrueType|OpenType)\)$/);
109
+ my $file = File::Spec->rel2abs($fd->{$font}, $ENV{'windir'}.'\\fonts');
110
+ add_file_to_font_hash($file);
111
+ }
112
+ }
113
+
114
+ sub font_search_file {
115
+ add_file_to_font_hash($_);
116
+ }
117
+
118
+ sub findfont($) {
119
+ my($fontname) = @_;
120
+ my $win32 = eval {
121
+ require Font::TTF::Win32;
122
+ Font::TTF::Win32->import();
123
+ 1;
124
+ };
125
+ my($file, $psname, $fontdata);
126
+
127
+ if (exists($font_info_hash{$fontname})) {
128
+ return $font_info_hash{$fontname};
129
+ }
130
+
131
+ # Are we on a system that uses fontconfig?
132
+ # NOTE: use a single string for the command here, or this
133
+ # script dies horribly on Windows, even though this isn't really
134
+ # applicable there...
135
+ if (open(my $fh, '-|',
136
+ "fc-match -f \"%{file}\\n%{postscriptname}\\n\" ".
137
+ "\" : postscriptname=$fontname\"")) {
138
+ chomp($file = <$fh>);
139
+ chomp($psname = <$fh>);
140
+ close($fh);
141
+ if ( -f $file ) {
142
+ if ($psname eq $fontname) {
143
+ add_file_to_font_hash($file);
144
+ }
145
+ if (!exists($font_info_hash{$fontname})) {
146
+ $font_info_hash{$fontname} = undef;
147
+ }
148
+ return $font_info_hash{$fontname};
149
+ }
150
+ }
151
+
152
+ if (exists($font_info_hash{$fontname})) {
153
+ return $font_info_hash{$fontname};
154
+ } elsif ($fonts_scanned >= 1) {
155
+ return $font_info_hash{$fontname} = undef;
156
+ }
157
+
158
+ scanfonts_win32();
159
+ $fonts_scanned = 1;
160
+
161
+ if (exists($font_info_hash{$fontname})) {
162
+ return $font_info_hash{$fontname};
163
+ } elsif ($fonts_scanned >= 2) {
164
+ return $font_info_hash{$fontname} = undef;
165
+ }
166
+
167
+ # Search a set of possible locations for a file, from a few different
168
+ # systems...
169
+ my @dirs = ('fonts', '/usr/share/fonts', '/usr/lib/fonts', '/Library/Fonts');
170
+ push @dirs, $ENV{'windir'}.'\\fonts' if (defined $ENV{'windir'});
171
+ push @dirs, $ENV{'HOME'}.'/.fonts', $ENV{'HOME'}.'/Library/Fonts'
172
+ if (defined $ENV{'HOME'});
173
+
174
+ find({wanted => \&font_search_file, follow=>1, no_chdir=>1}, @dirs);
175
+ $fonts_scanned = 2;
176
+
177
+ return $font_info_hash{$fontname};
178
+ }
179
+
180
+ 1;
@@ -0,0 +1,1294 @@
1
+ #!/usr/bin/perl
2
+ ## --------------------------------------------------------------------------
3
+ ##
4
+ ## Copyright 1996-2017 The NASM Authors - All Rights Reserved
5
+ ## See the file AUTHORS included with the NASM distribution for
6
+ ## the specific copyright holders.
7
+ ##
8
+ ## Redistribution and use in source and binary forms, with or without
9
+ ## modification, are permitted provided that the following
10
+ ## conditions are met:
11
+ ##
12
+ ## * Redistributions of source code must retain the above copyright
13
+ ## notice, this list of conditions and the following disclaimer.
14
+ ## * Redistributions in binary form must reproduce the above
15
+ ## copyright notice, this list of conditions and the following
16
+ ## disclaimer in the documentation and/or other materials provided
17
+ ## with the distribution.
18
+ ##
19
+ ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
20
+ ## CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
21
+ ## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22
+ ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ ## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24
+ ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26
+ ## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27
+ ## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
+ ## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29
+ ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30
+ ## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
31
+ ## EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+ ##
33
+ ## --------------------------------------------------------------------------
34
+
35
+ #
36
+ # Format the documentation as PostScript
37
+ #
38
+
39
+ use File::Spec;
40
+
41
+ require 'psfonts.ph'; # The fonts we want to use
42
+ require 'pswidth.ph'; # PostScript string width
43
+ require 'findfont.ph'; # Find fonts in the system
44
+
45
+ #
46
+ # Document formatting parameters
47
+ #
48
+ %psconf = (
49
+ pagewidth => 595, # Page width in PostScript points
50
+ pageheight => 792, # Page height in PostScript points
51
+ lmarg => 72*1.25, # Left margin in PostScript points
52
+ rmarg => 72, # Right margin in PostScript points
53
+ topmarg => 72, # Top margin in PostScript points
54
+ botmarg => 72, # Bottom margin in PostScript points
55
+ plmarg => 72*0.25, # Page number position relative to left margin
56
+ prmarg => 0, # Page number position relative to right margin
57
+ pymarg => 24, # Page number position relative to bot margin
58
+ startcopyright => 75, # How much above the bottom margin is the
59
+ # copyright notice stuff
60
+ bulladj => 12, # How much to indent a bullet/indented paragraph
61
+ tocind => 12, # TOC indentation per level
62
+ tocpnz => 24, # Width of TOC page number only zone
63
+ tocdots => 8, # Spacing between TOC dots
64
+ idxspace => 24, # Minimum space between index title and pg#
65
+ idxindent => 24, # How much to indent a subindex entry
66
+ idxgutter => 24, # Space between index columns
67
+ idxcolumns => 2, # Number of index columns
68
+
69
+ paraskip => 6, # Space between paragraphs
70
+ chapstart => 30, # Space before a chapter heading
71
+ chapskip => 24, # Space after a chapter heading
72
+ tocskip => 6, # Space between TOC entries
73
+ );
74
+
75
+ %psbool = (
76
+ colorlinks => 0, # Set links in blue rather than black
77
+ );
78
+
79
+ # Known paper sizes
80
+ %papersizes = (
81
+ 'a5' => [421, 595], # ISO half paper size
82
+ 'b5' => [501, 709], # ISO small paper size
83
+ 'a4' => [595, 842], # ISO standard paper size
84
+ 'letter' => [612, 792], # US common paper size
85
+ 'pa4' => [595, 792], # Compromise ("portable a4")
86
+ 'b4' => [709,1002], # ISO intermediate paper size
87
+ 'legal' => [612,1008], # US intermediate paper size
88
+ 'a3' => [842,1190], # ISO double paper size
89
+ '11x17' => [792,1224], # US double paper size
90
+ );
91
+
92
+ # Canned header file
93
+ $headps = 'head.ps';
94
+
95
+ # Directories
96
+ $fontsdir = 'fonts';
97
+ $epsdir = File::Spec->curdir();
98
+
99
+ #
100
+ # Parse the command line
101
+ #
102
+ undef $input;
103
+ while ( $arg = shift(@ARGV) ) {
104
+ if ( $arg =~ /^\-(|no\-)(.*)$/ ) {
105
+ $parm = $2;
106
+ $true = ($1 eq '') ? 1 : 0;
107
+ if ( $true && defined($papersizes{$parm}) ) {
108
+ $psconf{pagewidth} = $papersizes{$parm}->[0];
109
+ $psconf{pageheight} = $papersizes{$parm}->[1];
110
+ } elsif ( defined($psbool{$parm}) ) {
111
+ $psbool{$parm} = $true;
112
+ } elsif ( $true && defined($psconf{$parm}) ) {
113
+ $psconf{$parm} = shift(@ARGV);
114
+ } elsif ( $true && $parm =~ /^(title|subtitle|year|author|license)$/ ) {
115
+ $metadata{$parm} = shift(@ARGV);
116
+ } elsif ( $true && $parm eq 'fontsdir' ) {
117
+ $fontsdir = shift(@ARGV);
118
+ } elsif ( $true && $parm eq 'epsdir' ) {
119
+ $epsdir = shift(@ARGV);
120
+ } elsif ( $true && $parm eq 'headps' ) {
121
+ $headps = shift(@ARGV);
122
+ } else {
123
+ die "$0: Unknown option: $arg\n";
124
+ }
125
+ } else {
126
+ $input = $arg;
127
+ }
128
+ }
129
+
130
+ # Configure post-paragraph skips for each kind of paragraph
131
+ # (subject to modification above)
132
+ %skiparray = ('chap' => $psconf{chapskip},
133
+ 'appn' => $psconf{chapstart},
134
+ 'head' => $psconf{paraskip},
135
+ 'subh' => $psconf{paraskip},
136
+ 'norm' => $psconf{paraskip},
137
+ 'bull' => $psconf{paraskip},
138
+ 'indt' => $psconf{paraskip},
139
+ 'bquo' => $psconf{paraskip},
140
+ 'code' => $psconf{paraskip},
141
+ 'toc0' => $psconf{tocskip},
142
+ 'toc1' => $psconf{tocskip},
143
+ 'toc2' => $psconf{tocskip}
144
+ );
145
+
146
+ # Read the font metrics files, and update @AllFonts
147
+ # Get the list of fonts used
148
+ %ps_all_fonts = ();
149
+ %ps_font_subst = ();
150
+ foreach my $fset ( @AllFonts ) {
151
+ foreach my $font ( @{$fset->{fonts}} ) {
152
+ my $fdata;
153
+ my @flist = @{$font->[1]};
154
+ my $fname;
155
+ while (defined($fname = shift(@flist))) {
156
+ $fdata = findfont($fname);
157
+ last if (defined($fdata));
158
+ }
159
+ if (!defined($fdata)) {
160
+ die "$infile: no font found of: ".
161
+ join(', ', @{$font->[1]}), "\n".
162
+ "Install one of these fonts or update psfonts.ph\n";
163
+ }
164
+ $ps_all_fonts{$fname} = $fdata;
165
+ $font->[1] = $fdata;
166
+ }
167
+ }
168
+
169
+ # Custom encoding vector. This is basically the same as
170
+ # ISOLatin1Encoding (a level 2 feature, so we dont want to use it),
171
+ # but with the "naked" accents at \200-\237 moved to the \000-\037
172
+ # range (ASCII control characters), and a few extra characters thrown
173
+ # in. It is basically a modified Windows 1252 codepage, minus, for
174
+ # now, the euro sign (\200 is reserved for euro.)
175
+
176
+ @NASMEncoding =
177
+ (
178
+ undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
179
+ undef, undef, undef, undef, undef, undef, 'dotlessi', 'grave',
180
+ 'acute', 'circumflex', 'tilde', 'macron', 'breve', 'dotaccent',
181
+ 'dieresis', undef, 'ring', 'cedilla', undef, 'hungarumlaut',
182
+ 'ogonek', 'caron', 'space', 'exclam', 'quotedbl', 'numbersign',
183
+ 'dollar', 'percent', 'ampersand', 'quoteright', 'parenleft',
184
+ 'parenright', 'asterisk', 'plus', 'comma', 'minus', 'period',
185
+ 'slash', 'zero', 'one', 'two', 'three', 'four', 'five', 'six',
186
+ 'seven', 'eight', 'nine', 'colon', 'semicolon', 'less', 'equal',
187
+ 'greater', 'question', 'at', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
188
+ 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
189
+ 'W', 'X', 'Y', 'Z', 'bracketleft', 'backslash', 'bracketright',
190
+ 'asciicircum', 'underscore', 'quoteleft', 'a', 'b', 'c', 'd', 'e',
191
+ 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
192
+ 't', 'u', 'v', 'w', 'x', 'y', 'z', 'braceleft', 'bar', 'braceright',
193
+ 'asciitilde', undef, undef, undef, 'quotesinglbase', 'florin',
194
+ 'quotedblbase', 'ellipsis', 'dagger', 'dbldagger', 'circumflex',
195
+ 'perthousand', 'Scaron', 'guilsinglleft', 'OE', undef, 'Zcaron',
196
+ undef, undef, 'grave', 'quotesingle', 'quotedblleft',
197
+ 'quotedblright', 'bullet', 'endash', 'emdash', 'tilde', 'trademark',
198
+ 'scaron', 'guilsignlright', 'oe', undef, 'zcaron', 'Ydieresis',
199
+ 'space', 'exclamdown', 'cent', 'sterling', 'currency', 'yen',
200
+ 'brokenbar', 'section', 'dieresis', 'copyright', 'ordfeminine',
201
+ 'guillemotleft', 'logicalnot', 'hyphen', 'registered', 'macron',
202
+ 'degree', 'plusminus', 'twosuperior', 'threesuperior', 'acute', 'mu',
203
+ 'paragraph', 'periodcentered', 'cedilla', 'onesuperior',
204
+ 'ordmasculine', 'guillemotright', 'onequarter', 'onehalf',
205
+ 'threequarters', 'questiondown', 'Agrave', 'Aacute', 'Acircumflex',
206
+ 'Atilde', 'Adieresis', 'Aring', 'AE', 'Ccedilla', 'Egrave', 'Eacute',
207
+ 'Ecircumflex', 'Edieresis', 'Igrave', 'Iacute', 'Icircumflex',
208
+ 'Idieresis', 'Eth', 'Ntilde', 'Ograve', 'Oacute', 'Ocircumflex',
209
+ 'Otilde', 'Odieresis', 'multiply', 'Oslash', 'Ugrave', 'Uacute',
210
+ 'Ucircumflex', 'Udieresis', 'Yacute', 'Thorn', 'germandbls',
211
+ 'agrave', 'aacute', 'acircumflex', 'atilde', 'adieresis', 'aring',
212
+ 'ae', 'ccedilla', 'egrave', 'eacute', 'ecircumflex', 'edieresis',
213
+ 'igrave', 'iacute', 'icircumflex', 'idieresis', 'eth', 'ntilde',
214
+ 'ograve', 'oacute', 'ocircumflex', 'otilde', 'odieresis', 'divide',
215
+ 'oslash', 'ugrave', 'uacute', 'ucircumflex', 'udieresis', 'yacute',
216
+ 'thorn', 'ydieresis'
217
+ );
218
+
219
+ # Name-to-byte lookup hash
220
+ %charcode = ();
221
+ for ( $i = 0 ; $i < 256 ; $i++ ) {
222
+ $charcode{$NASMEncoding[$i]} = chr($i);
223
+ }
224
+
225
+ #
226
+ # First, format the stuff coming from the front end into
227
+ # a cleaner representation
228
+ #
229
+ if ( defined($input) ) {
230
+ open(PARAS, '<', $input) or
231
+ die "$0: cannot open $input: $!\n";
232
+ } else {
233
+ # stdin
234
+ open(PARAS, '<-') or die "$0: $!\n";
235
+ }
236
+ while ( defined($line = <PARAS>) ) {
237
+ chomp $line;
238
+ $data = <PARAS>;
239
+ chomp $data;
240
+ if ( $line =~ /^meta :(.*)$/ ) {
241
+ $metakey = $1;
242
+ $metadata{$metakey} = $data;
243
+ } elsif ( $line =~ /^indx :(.*)$/ ) {
244
+ $ixentry = $1;
245
+ push(@ixentries, $ixentry);
246
+ $ixterms{$ixentry} = [split(/\037/, $data)];
247
+ # Look for commas. This is easier done on the string
248
+ # representation, so do it now.
249
+ if ( $data =~ /^(.*)\,\037sp\037/ ) {
250
+ $ixprefix = $1;
251
+ $ixprefix =~ s/\037n $//; # Discard possible font change at end
252
+ $ixhasprefix{$ixentry} = $ixprefix;
253
+ if ( !$ixprefixes{$ixprefix} ) {
254
+ $ixcommafirst{$ixentry}++;
255
+ }
256
+ $ixprefixes{$ixprefix}++;
257
+ } else {
258
+ # A complete term can also be used as a prefix
259
+ $ixprefixes{$data}++;
260
+ }
261
+ } else {
262
+ push(@ptypes, $line);
263
+ push(@paras, [split(/\037/, $data)]);
264
+ }
265
+ }
266
+ close(PARAS);
267
+
268
+ #
269
+ # Convert an integer to a chosen base
270
+ #
271
+ sub int2base($$) {
272
+ my($i,$b) = @_;
273
+ my($s) = '';
274
+ my($n) = '';
275
+ my($z) = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
276
+ return '0' if ($i == 0);
277
+ if ( $i < 0 ) { $n = '-'; $i = -$i; }
278
+ while ( $i ) {
279
+ $s = substr($z,$i%$b,1) . $s;
280
+ $i = int($i/$b);
281
+ }
282
+ return $n.$s;
283
+ }
284
+
285
+ #
286
+ # Convert a string to a rendering array
287
+ #
288
+ sub string2array($)
289
+ {
290
+ my($s) = @_;
291
+ my(@a) = ();
292
+
293
+ $s =~ s/\B\-\-\B/$charcode{'emdash'}/g;
294
+ $s =~ s/\B\-\B/ $charcode{'endash'} /g;
295
+
296
+ while ( $s =~ /^(\s+|\S+)(.*)$/ ) {
297
+ push(@a, [0,$1]);
298
+ $s = $2;
299
+ }
300
+
301
+ return @a;
302
+ }
303
+
304
+ #
305
+ # Take a crossreference name and generate the PostScript name for it.
306
+ #
307
+ # This hack produces a somewhat smaller PDF...
308
+ #%ps_xref_list = ();
309
+ #$ps_xref_next = 0;
310
+ #sub ps_xref($) {
311
+ # my($s) = @_;
312
+ # my $q = $ps_xref_list{$s};
313
+ # return $q if ( defined($ps_xref_list{$s}) );
314
+ # $q = 'X'.int2base($ps_xref_next++, 52);
315
+ # $ps_xref_list{$s} = $q;
316
+ # return $q;
317
+ #}
318
+
319
+ # Somewhat bigger PDF, but one which obeys # URLs
320
+ sub ps_xref($) {
321
+ return @_[0];
322
+ }
323
+
324
+ #
325
+ # Flow lines according to a particular font set and width
326
+ #
327
+ # A "font set" is represented as an array containing
328
+ # arrays of pairs: [<size>, <metricref>]
329
+ #
330
+ # Each line is represented as:
331
+ # [ [type,first|last,aux,fontset,page,ypos,optional col],
332
+ # [rendering array] ]
333
+ #
334
+ # A space character may be "squeezed" by up to this much
335
+ # (as a fraction of the normal width of a space.)
336
+ #
337
+ $ps_space_squeeze = 0.00; # Min space width 100%
338
+ sub ps_flow_lines($$$@) {
339
+ my($wid, $fontset, $type, @data) = @_;
340
+ my($fonts) = $$fontset{fonts};
341
+ my($e);
342
+ my($w) = 0; # Width of current line
343
+ my($sw) = 0; # Width of current line due to spaces
344
+ my(@l) = (); # Current line
345
+ my(@ls) = (); # Accumulated output lines
346
+ my(@xd) = (); # Metadata that goes with subsequent text
347
+ my $hasmarker = 0; # Line has -6 marker
348
+ my $pastmarker = 0; # -6 marker found
349
+
350
+ # If there is a -6 marker anywhere in the paragraph,
351
+ # *each line* output needs to have a -6 marker
352
+ foreach $e ( @data ) {
353
+ $hasmarker = 1 if ( $$e[0] == -6 );
354
+ }
355
+
356
+ $w = 0;
357
+ foreach $e ( @data ) {
358
+ if ( $$e[0] < 0 ) {
359
+ # Type is metadata. Zero width.
360
+ if ( $$e[0] == -6 ) {
361
+ $pastmarker = 1;
362
+ }
363
+ if ( $$e[0] == -1 || $$e[0] == -6 ) {
364
+ # -1 (end anchor) or -6 (marker) goes with the preceeding
365
+ # text, otherwise with the subsequent text
366
+ push(@l, $e);
367
+ } else {
368
+ push(@xd, $e);
369
+ }
370
+ } else {
371
+ my $ew = ps_width($$e[1], $fontset->{fonts}->[$$e[0]][1],
372
+ \@NASMEncoding) *
373
+ ($fontset->{fonts}->[$$e[0]][0]);
374
+ my $sp = $$e[1];
375
+ $sp =~ tr/[^ ]//d; # Delete nonspaces
376
+ my $esw = ps_width($sp, $fontset->{fonts}->[$$e[0]][1],
377
+ \@NASMEncoding) *
378
+ ($fontset->{fonts}->[$$e[0]][0]);
379
+
380
+ if ( ($w+$ew) - $ps_space_squeeze*($sw+$esw) > $wid ) {
381
+ # Begin new line
382
+ # Search backwards for previous space chunk
383
+ my $lx = scalar(@l)-1;
384
+ my @rm = ();
385
+ while ( $lx >= 0 ) {
386
+ while ( $lx >= 0 && $l[$lx]->[0] < 0 ) {
387
+ # Skip metadata
388
+ $pastmarker = 0 if ( $l[$lx]->[0] == -6 );
389
+ $lx--;
390
+ };
391
+ if ( $lx >= 0 ) {
392
+ if ( $l[$lx]->[1] eq ' ' ) {
393
+ splice(@l, $lx, 1);
394
+ @rm = splice(@l, $lx);
395
+ last; # Found place to break
396
+ } else {
397
+ $lx--;
398
+ }
399
+ }
400
+ }
401
+
402
+ # Now @l contains the stuff to remain on the old line
403
+ # If we broke the line inside a link, then split the link
404
+ # into two.
405
+ my $lkref = undef;
406
+ foreach my $lc ( @l ) {
407
+ if ( $$lc[0] == -2 || $$lc[0] == -3 || $lc[0] == -7 ) {
408
+ $lkref = $lc;
409
+ } elsif ( $$lc[0] == -1 ) {
410
+ undef $lkref;
411
+ }
412
+ }
413
+
414
+ if ( defined($lkref) ) {
415
+ push(@l, [-1,undef]); # Terminate old reference
416
+ unshift(@rm, $lkref); # Duplicate reference on new line
417
+ }
418
+
419
+ if ( $hasmarker ) {
420
+ if ( $pastmarker ) {
421
+ unshift(@rm,[-6,undef]); # New line starts with marker
422
+ } else {
423
+ push(@l,[-6,undef]); # Old line ends with marker
424
+ }
425
+ }
426
+
427
+ push(@ls, [[$type,0,undef,$fontset,0,0],[@l]]);
428
+ @l = @rm;
429
+
430
+ $w = $sw = 0;
431
+ # Compute the width of the remainder array
432
+ for my $le ( @l ) {
433
+ if ( $$le[0] >= 0 ) {
434
+ my $xew = ps_width($$le[1],
435
+ $fontset->{fonts}->[$$le[0]][1],
436
+ \@NASMEncoding) *
437
+ ($fontset->{fonts}->[$$le[0]][0]);
438
+ my $xsp = $$le[1];
439
+ $xsp =~ tr/[^ ]//d; # Delete nonspaces
440
+ my $xsw = ps_width($xsp,
441
+ $fontset->{fonts}->[$$le[0]][1],
442
+ \@NASMEncoding) *
443
+ ($fontset->{fonts}->[$$le[0]][0]);
444
+ $w += $xew; $sw += $xsw;
445
+ }
446
+ }
447
+ }
448
+ push(@l, @xd); # Accumulated metadata
449
+ @xd = ();
450
+ if ( $$e[1] ne '' ) {
451
+ push(@l, $e);
452
+ $w += $ew; $sw += $esw;
453
+ }
454
+ }
455
+ }
456
+ push(@l,@xd);
457
+ if ( scalar(@l) ) {
458
+ push(@ls, [[$type,0,undef,$fontset,0,0],[@l]]); # Final line
459
+ }
460
+
461
+ # Mark the first line as first and the last line as last
462
+ if ( scalar(@ls) ) {
463
+ $ls[0]->[0]->[1] |= 1; # First in para
464
+ $ls[-1]->[0]->[1] |= 2; # Last in para
465
+ }
466
+ return @ls;
467
+ }
468
+
469
+ #
470
+ # Once we have broken things into lines, having multiple chunks
471
+ # with the same font index is no longer meaningful. Merge
472
+ # adjacent chunks to keep down the size of the whole file.
473
+ #
474
+ sub ps_merge_chunks(@) {
475
+ my(@ci) = @_;
476
+ my($c, $lc);
477
+ my(@co, $eco);
478
+
479
+ undef $lc;
480
+ @co = ();
481
+ $eco = -1; # Index of the last entry in @co
482
+ foreach $c ( @ci ) {
483
+ if ( defined($lc) && $$c[0] == $lc && $$c[0] >= 0 ) {
484
+ $co[$eco]->[1] .= $$c[1];
485
+ } else {
486
+ push(@co, $c); $eco++;
487
+ $lc = $$c[0];
488
+ }
489
+ }
490
+ return @co;
491
+ }
492
+
493
+ #
494
+ # Convert paragraphs to rendering arrays. Each
495
+ # element in the array contains (font, string),
496
+ # where font can be one of:
497
+ # -1 end link
498
+ # -2 begin crossref
499
+ # -3 begin weblink
500
+ # -4 index item anchor
501
+ # -5 crossref anchor
502
+ # -6 left/right marker (used in the index)
503
+ # -7 page link (used in the index)
504
+ # 0 normal
505
+ # 1 empatic (italic)
506
+ # 2 code (fixed spacing)
507
+ #
508
+
509
+ sub mkparaarray($@) {
510
+ my($ptype, @chunks) = @_;
511
+
512
+ my @para = ();
513
+ my $in_e = 0;
514
+ my $chunk;
515
+
516
+ if ( $ptype =~ /^code/ ) {
517
+ foreach $chunk ( @chunks ) {
518
+ push(@para, [2, $chunk]);
519
+ }
520
+ } else {
521
+ foreach $chunk ( @chunks ) {
522
+ my $type = substr($chunk,0,2);
523
+ my $text = substr($chunk,2);
524
+
525
+ if ( $type eq 'sp' ) {
526
+ push(@para, [$in_e?1:0, ' ']);
527
+ } elsif ( $type eq 'da' ) {
528
+ push(@para, [$in_e?1:0, $charcode{'endash'}]);
529
+ } elsif ( $type eq 'n ' ) {
530
+ push(@para, [0, $text]);
531
+ $in_e = 0;
532
+ } elsif ( $type =~ '^e' ) {
533
+ push(@para, [1, $text]);
534
+ $in_e = ($type eq 'es' || $type eq 'e ');
535
+ } elsif ( $type eq 'c ' ) {
536
+ push(@para, [2, $text]);
537
+ $in_e = 0;
538
+ } elsif ( $type eq 'x ' ) {
539
+ push(@para, [-2, ps_xref($text)]);
540
+ } elsif ( $type eq 'xe' ) {
541
+ push(@para, [-1, undef]);
542
+ } elsif ( $type eq 'wc' || $type eq 'w ' ) {
543
+ $text =~ /\<(.*)\>(.*)$/;
544
+ my $link = $1; $text = $2;
545
+ push(@para, [-3, $link]);
546
+ push(@para, [($type eq 'wc') ? 2:0, $text]);
547
+ push(@para, [-1, undef]);
548
+ $in_e = 0;
549
+ } elsif ( $type eq 'i ' ) {
550
+ push(@para, [-4, $text]);
551
+ } else {
552
+ die "Unexpected paragraph chunk: $chunk";
553
+ }
554
+ }
555
+ }
556
+ return @para;
557
+ }
558
+
559
+ $npara = scalar(@paras);
560
+ for ( $i = 0 ; $i < $npara ; $i++ ) {
561
+ $paras[$i] = [mkparaarray($ptypes[$i], @{$paras[$i]})];
562
+ }
563
+
564
+ #
565
+ # This converts a rendering array to a simple string
566
+ #
567
+ sub ps_arraytostr(@) {
568
+ my $s = '';
569
+ my $c;
570
+ foreach $c ( @_ ) {
571
+ $s .= $$c[1] if ( $$c[0] >= 0 );
572
+ }
573
+ return $s;
574
+ }
575
+
576
+ #
577
+ # This generates a duplicate of a paragraph
578
+ #
579
+ sub ps_dup_para(@) {
580
+ my(@i) = @_;
581
+ my(@o) = ();
582
+ my($c);
583
+
584
+ foreach $c ( @i ) {
585
+ my @cc = @{$c};
586
+ push(@o, [@cc]);
587
+ }
588
+ return @o;
589
+ }
590
+
591
+ #
592
+ # This generates a duplicate of a paragraph, stripping anchor
593
+ # tags (-4 and -5)
594
+ #
595
+ sub ps_dup_para_noanchor(@) {
596
+ my(@i) = @_;
597
+ my(@o) = ();
598
+ my($c);
599
+
600
+ foreach $c ( @i ) {
601
+ my @cc = @{$c};
602
+ push(@o, [@cc]) unless ( $cc[0] == -4 || $cc[0] == -5 );
603
+ }
604
+ return @o;
605
+ }
606
+
607
+ #
608
+ # Scan for header paragraphs and fix up their contents;
609
+ # also generate table of contents and PDF bookmarks.
610
+ #
611
+ @tocparas = ([[-5, 'contents'], [0,'Contents']]);
612
+ @tocptypes = ('chap');
613
+ @bookmarks = (['title', 0, 'Title'], ['contents', 0, 'Contents']);
614
+ %bookref = ();
615
+ for ( $i = 0 ; $i < $npara ; $i++ ) {
616
+ my $xtype = $ptypes[$i];
617
+ my $ptype = substr($xtype,0,4);
618
+ my $str;
619
+ my $book;
620
+
621
+ if ( $ptype eq 'chap' || $ptype eq 'appn' ) {
622
+ unless ( $xtype =~ /^\S+ (\S+) :(.*)$/ ) {
623
+ die "Bad para";
624
+ }
625
+ my $secn = $1;
626
+ my $sech = $2;
627
+ my $xref = ps_xref($sech);
628
+ my $chap = ($ptype eq 'chap')?'Chapter':'Appendix';
629
+
630
+ $book = [$xref, 0, ps_arraytostr(@{$paras[$i]})];
631
+ push(@bookmarks, $book);
632
+ $bookref{$secn} = $book;
633
+
634
+ push(@tocparas, [ps_dup_para_noanchor(@{$paras[$i]})]);
635
+ push(@tocptypes, 'toc0'.' :'.$sech.':'.$chap.' '.$secn.':');
636
+
637
+ unshift(@{$paras[$i]},
638
+ [-5, $xref], [0,$chap.' '.$secn.':'], [0, ' ']);
639
+ } elsif ( $ptype eq 'head' || $ptype eq 'subh' ) {
640
+ unless ( $xtype =~ /^\S+ (\S+) :(.*)$/ ) {
641
+ die "Bad para";
642
+ }
643
+ my $secn = $1;
644
+ my $sech = $2;
645
+ my $xref = ps_xref($sech);
646
+ my $pref;
647
+ $pref = $secn; $pref =~ s/\.[^\.]+$//; # Find parent node
648
+
649
+ $book = [$xref, 0, ps_arraytostr(@{$paras[$i]})];
650
+ push(@bookmarks, $book);
651
+ $bookref{$secn} = $book;
652
+ $bookref{$pref}->[1]--; # Adjust count for parent node
653
+
654
+ push(@tocparas, [ps_dup_para_noanchor(@{$paras[$i]})]);
655
+ push(@tocptypes,
656
+ (($ptype eq 'subh') ? 'toc2':'toc1').' :'.$sech.':'.$secn);
657
+
658
+ unshift(@{$paras[$i]}, [-5, $xref]);
659
+ }
660
+ }
661
+
662
+ #
663
+ # Add TOC to beginning of paragraph list
664
+ #
665
+ unshift(@paras, @tocparas); undef @tocparas;
666
+ unshift(@ptypes, @tocptypes); undef @tocptypes;
667
+
668
+ #
669
+ # Add copyright notice to the beginning
670
+ #
671
+ @copyright_page =
672
+ ([[0, $charcode{'copyright'}],
673
+ [0, ' '], [0, $metadata{'year'}],
674
+ [0, ' '], string2array($metadata{'author'}),
675
+ [0, ' '], string2array($metadata{'copyright_tail'})],
676
+ [string2array($metadata{'license'})],
677
+ [string2array($metadata{'auxinfo'})]);
678
+
679
+ unshift(@paras, @copyright_page);
680
+ unshift(@ptypes, ('norm') x scalar(@copyright_page));
681
+
682
+ $npara = scalar(@paras);
683
+
684
+ #
685
+ # No lines generated, yet.
686
+ #
687
+ @pslines = ();
688
+
689
+ #
690
+ # Line Auxilliary Information Types
691
+ #
692
+ $AuxStr = 1; # String
693
+ $AuxPage = 2; # Page number (from xref)
694
+ $AuxPageStr = 3; # Page number as a PostScript string
695
+ $AuxXRef = 4; # Cross reference as a name
696
+ $AuxNum = 5; # Number
697
+
698
+ #
699
+ # Break or convert paragraphs into lines, and push them
700
+ # onto the @pslines array.
701
+ #
702
+ sub ps_break_lines($$) {
703
+ my ($paras,$ptypes) = @_;
704
+
705
+ my $linewidth = $psconf{pagewidth}-$psconf{lmarg}-$psconf{rmarg};
706
+ my $bullwidth = $linewidth-$psconf{bulladj};
707
+ my $indxwidth = ($linewidth-$psconf{idxgutter})/$psconf{idxcolumns}
708
+ -$psconf{idxspace};
709
+
710
+ my $npara = scalar(@{$paras});
711
+ my $i;
712
+
713
+ for ( $i = 0 ; $i < $npara ; $i++ ) {
714
+ my $xtype = $ptypes->[$i];
715
+ my $ptype = substr($xtype,0,4);
716
+ my @data = @{$paras->[$i]};
717
+ my @ls = ();
718
+ if ( $ptype eq 'code' ) {
719
+ my $p;
720
+ # Code paragraph; each chunk is a line
721
+ foreach $p ( @data ) {
722
+ push(@ls, [[$ptype,0,undef,\%BodyFont,0,0],[$p]]);
723
+ }
724
+ $ls[0]->[0]->[1] |= 1; # First in para
725
+ $ls[-1]->[0]->[1] |= 2; # Last in para
726
+ } elsif ( $ptype eq 'chap' || $ptype eq 'appn' ) {
727
+ # Chapters are flowed normally, but in an unusual font
728
+ @ls = ps_flow_lines($linewidth, \%ChapFont, $ptype, @data);
729
+ } elsif ( $ptype eq 'head' || $ptype eq 'subh' ) {
730
+ unless ( $xtype =~ /^\S+ (\S+) :(.*)$/ ) {
731
+ die "Bad para";
732
+ }
733
+ my $secn = $1;
734
+ my $sech = $2;
735
+ my $font = ($ptype eq 'head') ? \%HeadFont : \%SubhFont;
736
+ @ls = ps_flow_lines($linewidth, $font, $ptype, @data);
737
+ # We need the heading number as auxillary data
738
+ $ls[0]->[0]->[2] = [[$AuxStr,$secn]];
739
+ } elsif ( $ptype eq 'norm' ) {
740
+ @ls = ps_flow_lines($linewidth, \%BodyFont, $ptype, @data);
741
+ } elsif ( $ptype =~ /^(bull|indt)$/ ) {
742
+ @ls = ps_flow_lines($bullwidth, \%BodyFont, $ptype, @data);
743
+ } elsif ( $ptypq eq 'bquo' ) {
744
+ @ls = ps_flow_lines($bullwidth, \%BquoFont, $ptype, @data);
745
+ } elsif ( $ptype =~ /^toc/ ) {
746
+ unless ( $xtype =~/^\S+ :([^:]*):(.*)$/ ) {
747
+ die "Bad para";
748
+ }
749
+ my $xref = $1;
750
+ my $refname = $2.' ';
751
+ my $ntoc = substr($ptype,3,1)+0;
752
+ my $refwidth = ps_width($refname, $BodyFont{fonts}->[0][1],
753
+ \@NASMEncoding) *
754
+ ($BodyFont{fonts}->[0][0]);
755
+
756
+ @ls = ps_flow_lines($linewidth-$ntoc*$psconf{tocind}-
757
+ $psconf{tocpnz}-$refwidth,
758
+ \%BodyFont, $ptype, @data);
759
+
760
+ # Auxilliary data: for the first line, the cross reference symbol
761
+ # and the reference name; for all lines but the first, the
762
+ # reference width; and for the last line, the page number
763
+ # as a string.
764
+ my $nl = scalar(@ls);
765
+ $ls[0]->[0]->[2] = [[$AuxStr,$refname], [$AuxXRef,$xref]];
766
+ for ( $j = 1 ; $j < $nl ; $j++ ) {
767
+ $ls[$j]->[0]->[2] = [[$AuxNum,$refwidth]];
768
+ }
769
+ push(@{$ls[$nl-1]->[0]->[2]}, [$AuxPageStr,$xref]);
770
+ } elsif ( $ptype =~ /^idx/ ) {
771
+ my $lvl = substr($ptype,3,1)+0;
772
+
773
+ @ls = ps_flow_lines($indxwidth-$lvl*$psconf{idxindent},
774
+ \%BodyFont, $ptype, @data);
775
+ } else {
776
+ die "Unknown para type: $ptype";
777
+ }
778
+ # Merge adjacent identical chunks
779
+ foreach $l ( @ls ) {
780
+ @{$$l[1]} = ps_merge_chunks(@{$$l[1]});
781
+ }
782
+ push(@pslines,@ls);
783
+ }
784
+ }
785
+
786
+ # Break the main body text into lines.
787
+ ps_break_lines(\@paras, \@ptypes);
788
+
789
+ #
790
+ # Break lines in to pages
791
+ #
792
+
793
+ # Where to start on page 2, the copyright page
794
+ $curpage = 2; # Start on page 2
795
+ $curypos = $psconf{pageheight}-$psconf{topmarg}-$psconf{botmarg}-
796
+ $psconf{startcopyright};
797
+ undef $columnstart; # Not outputting columnar text
798
+ undef $curcolumn; # Current column
799
+ $nlines = scalar(@pslines);
800
+
801
+ #
802
+ # This formats lines inside the global @pslines array into pages,
803
+ # updating the page and y-coordinate entries. Start at the
804
+ # $startline position in @pslines and go to but not including
805
+ # $endline. The global variables $curpage, $curypos, $columnstart
806
+ # and $curcolumn are updated appropriately.
807
+ #
808
+ sub ps_break_pages($$) {
809
+ my($startline, $endline) = @_;
810
+
811
+ # Paragraph types which should never be broken
812
+ my $nobreakregexp = "^(chap|appn|head|subh|toc.|idx.)\$";
813
+ # Paragraph types which are heading (meaning they should not be broken
814
+ # immediately after)
815
+ my $nobreakafter = "^(chap|appn|head|subh)\$";
816
+ # Paragraph types which should never be broken *before*
817
+ my $nobreakbefore = "^idx[1-9]\$";
818
+ # Paragraph types which are set in columnar format
819
+ my $columnregexp = "^idx.\$";
820
+
821
+ my $upageheight = $psconf{pageheight}-$psconf{topmarg}-$psconf{botmarg};
822
+
823
+ my $i;
824
+
825
+ for ( $i = $startline ; $i < $endline ; $i++ ) {
826
+ my $linfo = $pslines[$i]->[0];
827
+ if ( ($$linfo[0] eq 'chap' || $$linfo[0] eq 'appn' )
828
+ && ($$linfo[1] & 1) ) {
829
+ # First line of a new chapter heading. Start a new page.
830
+ undef $columnstart;
831
+ $curpage++ if ( $curypos > 0 || defined($columnstart) );
832
+ # Always start on an odd page
833
+ $curpage |= 1;
834
+ $curypos = $chapstart;
835
+ } elsif ( defined($columnstart) && $$linfo[0] !~ /$columnregexp/o ) {
836
+ undef $columnstart;
837
+ $curpage++;
838
+ $curypos = 0;
839
+ }
840
+
841
+ if ( $$linfo[0] =~ /$columnregexp/o && !defined($columnstart) ) {
842
+ $columnstart = $curypos;
843
+ $curcolumn = 0;
844
+ }
845
+
846
+ # Adjust position by the appropriate leading
847
+ $curypos += $$linfo[3]->{leading};
848
+
849
+ # Record the page and y-position
850
+ $$linfo[4] = $curpage;
851
+ $$linfo[5] = $curypos;
852
+ $$linfo[6] = $curcolumn if ( defined($columnstart) );
853
+
854
+ if ( $curypos > $upageheight ) {
855
+ # We need to break the page before this line.
856
+ my $broken = 0; # No place found yet
857
+ while ( !$broken && $pslines[$i]->[0]->[4] == $curpage ) {
858
+ my $linfo = $pslines[$i]->[0];
859
+ my $pinfo = $pslines[$i-1]->[0];
860
+
861
+ if ( $$linfo[1] == 2 ) {
862
+ # This would be an orphan, don't break.
863
+ } elsif ( $$linfo[1] & 1 ) {
864
+ # Sole line or start of paragraph. Break unless
865
+ # the previous line was part of a heading.
866
+ $broken = 1 if ( $$pinfo[0] !~ /$nobreakafter/o &&
867
+ $$linfo[0] !~ /$nobreakbefore/o );
868
+ } else {
869
+ # Middle of paragraph. Break unless we're in a
870
+ # no-break paragraph, or the previous line would
871
+ # end up being a widow.
872
+ $broken = 1 if ( $$linfo[0] !~ /$nobreakregexp/o &&
873
+ $$pinfo[1] != 1 );
874
+ }
875
+ $i--;
876
+ }
877
+ die "Nowhere to break page $curpage\n" if ( !$broken );
878
+ # Now $i should point to line immediately before the break, i.e.
879
+ # the next paragraph should be the first on the new page
880
+ if ( defined($columnstart) &&
881
+ ++$curcolumn < $psconf{idxcolumns} ) {
882
+ # We're actually breaking text into columns, not pages
883
+ $curypos = $columnstart;
884
+ } else {
885
+ undef $columnstart;
886
+ $curpage++;
887
+ $curypos = 0;
888
+ }
889
+ next;
890
+ }
891
+
892
+ # Add end of paragraph skip
893
+ if ( $$linfo[1] & 2 ) {
894
+ $curypos += $skiparray{$$linfo[0]};
895
+ }
896
+ }
897
+ }
898
+
899
+ ps_break_pages(0,$nlines); # Break the main text body into pages
900
+
901
+ #
902
+ # Find the page number of all the indices
903
+ #
904
+ %ps_xref_page = (); # Crossref anchor pages
905
+ %ps_index_pages = (); # Index item pages
906
+ $nlines = scalar(@pslines);
907
+ for ( $i = 0 ; $i < $nlines ; $i++ ) {
908
+ my $linfo = $pslines[$i]->[0];
909
+ foreach my $c ( @{$pslines[$i]->[1]} ) {
910
+ if ( $$c[0] == -4 ) {
911
+ if ( !defined($ps_index_pages{$$c[1]}) ) {
912
+ $ps_index_pages{$$c[1]} = [];
913
+ } elsif ( $ps_index_pages{$$c[1]}->[-1] eq $$linfo[4] ) {
914
+ # Pages are emitted in order; if this is a duplicated
915
+ # entry it will be the last one
916
+ next; # Duplicate
917
+ }
918
+ push(@{$ps_index_pages{$$c[1]}}, $$linfo[4]);
919
+ } elsif ( $$c[0] == -5 ) {
920
+ $ps_xref_page{$$c[1]} = $$linfo[4];
921
+ }
922
+ }
923
+ }
924
+
925
+ #
926
+ # Emit index paragraphs
927
+ #
928
+ $startofindex = scalar(@pslines);
929
+ @ixparas = ([[-5,'index'],[0,'Index']]);
930
+ @ixptypes = ('chap');
931
+
932
+ foreach $k ( @ixentries ) {
933
+ my $n,$i;
934
+ my $ixptype = 'idx0';
935
+ my $prefix = $ixhasprefix{$k};
936
+ my @ixpara = mkparaarray($ixptype,@{$ixterms{$k}});
937
+ my $commapos = undef;
938
+
939
+ if ( defined($prefix) && $ixprefixes{$prefix} > 1 ) {
940
+ # This entry has a "hanging comma"
941
+ for ( $i = 0 ; $i < scalar(@ixpara)-1 ; $i++ ) {
942
+ if ( substr($ixpara[$i]->[1],-1,1) eq ',' &&
943
+ $ixpara[$i+1]->[1] eq ' ' ) {
944
+ $commapos = $i;
945
+ last;
946
+ }
947
+ }
948
+ }
949
+ if ( defined($commapos) ) {
950
+ if ( $ixcommafirst{$k} ) {
951
+ # This is the first entry; generate the
952
+ # "hanging comma" entry
953
+ my @precomma = splice(@ixpara,0,$commapos);
954
+ if ( $ixpara[0]->[1] eq ',' ) {
955
+ shift(@ixpara); # Discard lone comma
956
+ } else {
957
+ # Discard attached comma
958
+ $ixpara[0]->[1] =~ s/\,$//;
959
+ push(@precomma,shift(@ixpara));
960
+ }
961
+ push(@precomma, [-6,undef]);
962
+ push(@ixparas, [@precomma]);
963
+ push(@ixptypes, $ixptype);
964
+ shift(@ixpara); # Remove space
965
+ } else {
966
+ splice(@ixpara,0,$commapos+2);
967
+ }
968
+ $ixptype = 'idx1';
969
+ }
970
+
971
+ push(@ixpara, [-6,undef]); # Left/right marker
972
+ $i = 1; $n = scalar(@{$ps_index_pages{$k}});
973
+ foreach $p ( @{$ps_index_pages{$k}} ) {
974
+ if ( $i++ == $n ) {
975
+ push(@ixpara,[-7,$p],[0,"$p"],[-1,undef]);
976
+ } else {
977
+ push(@ixpara,[-7,$p],[0,"$p,"],[-1,undef],[0,' ']);
978
+ }
979
+ }
980
+
981
+ push(@ixparas, [@ixpara]);
982
+ push(@ixptypes, $ixptype);
983
+ }
984
+
985
+ #
986
+ # Flow index paragraphs into lines
987
+ #
988
+ ps_break_lines(\@ixparas, \@ixptypes);
989
+
990
+ #
991
+ # Format index into pages
992
+ #
993
+ $nlines = scalar(@pslines);
994
+ ps_break_pages($startofindex, $nlines);
995
+
996
+ #
997
+ # Push index onto bookmark list
998
+ #
999
+ push(@bookmarks, ['index', 0, 'Index']);
1000
+
1001
+ @all_fonts_lst = sort(keys(%ps_all_fonts));
1002
+ $all_fonts_str = join(' ', @all_fonts_lst);
1003
+ @need_fonts_lst = ();
1004
+ foreach my $f (@all_fonts_lst) {
1005
+ push(@need_fonts_lst, $f); # unless (defined($ps_all_fonts{$f}->{file}));
1006
+ }
1007
+ $need_fonts_str = join(' ', @need_fonts_lst);
1008
+
1009
+ # Emit the PostScript DSC header
1010
+ print "%!PS-Adobe-3.0\n";
1011
+ print "%%Pages: $curpage\n";
1012
+ print "%%BoundingBox: 0 0 ", $psconf{pagewidth}, ' ', $psconf{pageheight}, "\n";
1013
+ print "%%Creator: (NASM psflow.pl)\n";
1014
+ print "%%DocumentData: Clean7Bit\n";
1015
+ print "%%DocumentFonts: $all_fonts_str\n";
1016
+ print "%%DocumentNeededFonts: $need_fonts_str\n";
1017
+ print "%%Orientation: Portrait\n";
1018
+ print "%%PageOrder: Ascend\n";
1019
+ print "%%EndComments\n";
1020
+ print "%%BeginProlog\n";
1021
+
1022
+ # Emit the configurables as PostScript tokens
1023
+ foreach $c ( keys(%psconf) ) {
1024
+ print "/$c ", $psconf{$c}, " def\n";
1025
+ }
1026
+ foreach $c ( keys(%psbool) ) {
1027
+ print "/$c ", ($psbool{$c}?'true':'false'), " def\n";
1028
+ }
1029
+
1030
+ # Embed font data, if applicable
1031
+ #foreach my $f (@all_fonts_lst) {
1032
+ # my $fontfile = $all_ps_fonts{$f}->{file};
1033
+ # if (defined($fontfile)) {
1034
+ # if (open(my $fh, '<', $fontfile)) {
1035
+ # print vector <$fh>;
1036
+ # close($fh);
1037
+ # }
1038
+ # }
1039
+ #}
1040
+
1041
+ # Emit custom encoding vector
1042
+ $zstr = '/NASMEncoding [ ';
1043
+ foreach $c ( @NASMEncoding ) {
1044
+ my $z = '/'.(defined($c)?$c:'.notdef ').' ';
1045
+ if ( length($zstr)+length($z) > 72 ) {
1046
+ print $zstr,"\n";
1047
+ $zstr = ' ';
1048
+ }
1049
+ $zstr .= $z;
1050
+ }
1051
+ print $zstr, "] def\n";
1052
+
1053
+ # Font recoding routine
1054
+ # newname fontname --
1055
+ print "/nasmenc {\n";
1056
+ print " findfont dup length dict begin\n";
1057
+ print " { 1 index /FID ne {def}{pop pop} ifelse } forall\n";
1058
+ print " /Encoding NASMEncoding def\n";
1059
+ print " currentdict\n";
1060
+ print " end\n";
1061
+ print " definefont pop\n";
1062
+ print "} def\n";
1063
+
1064
+ # Emit fontset definitions
1065
+ foreach $font ( sort(keys(%ps_all_fonts)) ) {
1066
+ print '/',$font,'-NASM /',$font," nasmenc\n";
1067
+ }
1068
+
1069
+ foreach $fset ( @AllFonts ) {
1070
+ my $i = 0;
1071
+ my @zfonts = ();
1072
+ foreach $font ( @{$fset->{fonts}} ) {
1073
+ print '/', $fset->{name}, $i, ' ',
1074
+ '/', $font->[1]->{name}, '-NASM findfont ',
1075
+ $font->[0], " scalefont def\n";
1076
+ push(@zfonts, $fset->{name}.$i);
1077
+ $i++;
1078
+ }
1079
+ print '/', $fset->{name}, ' [', join(' ',@zfonts), "] def\n";
1080
+ }
1081
+
1082
+ # This is used by the bullet-paragraph PostScript methods
1083
+ print "/bullet [",ps_string($charcode{'bullet'}),"] def\n";
1084
+
1085
+ # Emit the canned PostScript prologue
1086
+ open(PSHEAD, '<', $headps)
1087
+ or die "$0: cannot open: $headps: $!\n";
1088
+ while ( defined($line = <PSHEAD>) ) {
1089
+ print $line;
1090
+ }
1091
+ close(PSHEAD);
1092
+ print "%%EndProlog\n";
1093
+
1094
+ # Generate a PostScript string
1095
+ sub ps_string($) {
1096
+ my ($s) = @_;
1097
+ my ($i,$c);
1098
+ my ($o) = '(';
1099
+ my ($l) = length($s);
1100
+ for ( $i = 0 ; $i < $l ; $i++ ) {
1101
+ $c = substr($s,$i,1);
1102
+ if ( ord($c) < 32 || ord($c) > 126 ) {
1103
+ $o .= sprintf("\\%03o", ord($c));
1104
+ } elsif ( $c eq '(' || $c eq ')' || $c eq "\\" ) {
1105
+ $o .= "\\".$c;
1106
+ } else {
1107
+ $o .= $c;
1108
+ }
1109
+ }
1110
+ return $o.')';
1111
+ }
1112
+
1113
+ # Generate PDF bookmarks
1114
+ print "%%BeginSetup\n";
1115
+ foreach $b ( @bookmarks ) {
1116
+ print '[/Title ', ps_string($b->[2]), "\n";
1117
+ print '/Count ', $b->[1], ' ' if ( $b->[1] );
1118
+ print '/Dest /',$b->[0]," /OUT pdfmark\n";
1119
+ }
1120
+
1121
+ # Ask the PostScript interpreter for the proper size media
1122
+ print "setpagesize\n";
1123
+ print "%%EndSetup\n";
1124
+
1125
+ # Start a PostScript page
1126
+ sub ps_start_page() {
1127
+ $ps_page++;
1128
+ print "%%Page: $ps_page $ps_page\n";
1129
+ print "%%BeginPageSetup\n";
1130
+ print "save\n";
1131
+ print "%%EndPageSetup\n";
1132
+ print '/', $ps_page, " pa\n";
1133
+ }
1134
+
1135
+ # End a PostScript page
1136
+ sub ps_end_page($) {
1137
+ my($pn) = @_;
1138
+ if ( $pn ) {
1139
+ print "($ps_page)", (($ps_page & 1) ? 'pageodd' : 'pageeven'), "\n";
1140
+ }
1141
+ print "restore showpage\n";
1142
+ }
1143
+
1144
+ $ps_page = 0;
1145
+
1146
+ # Title page
1147
+ ps_start_page();
1148
+ $title = $metadata{'title'} || '';
1149
+ $title =~ s/ \- / $charcode{'endash'} /;
1150
+
1151
+ $subtitle = $metadata{'subtitle'} || '';
1152
+ $subtitle =~ s/ \- / $charcode{'endash'} /;
1153
+
1154
+ # Print title
1155
+ print "/ti ", ps_string($title), " def\n";
1156
+ print "/sti ", ps_string($subtitle), " def\n";
1157
+ print "lmarg pageheight 2 mul 3 div moveto\n";
1158
+ print "tfont0 setfont\n";
1159
+ print "/title linkdest ti show\n";
1160
+ print "lmarg pageheight 2 mul 3 div 10 sub moveto\n";
1161
+ print "0 setlinecap 3 setlinewidth\n";
1162
+ print "pagewidth lmarg sub rmarg sub 0 rlineto currentpoint stroke moveto\n";
1163
+ print "hfont1 setfont sti stringwidth pop neg ",
1164
+ -$HeadFont{leading}, " rmoveto\n";
1165
+ print "sti show\n";
1166
+
1167
+ # Print logo, if there is one
1168
+ # FIX: To be 100% correct, this should look for DocumentNeeded*
1169
+ # and DocumentFonts in the header of the EPSF and add those to the
1170
+ # global header.
1171
+ if ( defined($metadata{epslogo}) &&
1172
+ open(EPS, '<', File::Spec->catfile($epsdir, $metadata{epslogo})) ) {
1173
+ my @eps = ();
1174
+ my ($bbllx,$bblly,$bburx,$bbury) = (undef,undef,undef,undef);
1175
+ my $line;
1176
+ my $scale = 1;
1177
+ my $maxwidth = $psconf{pagewidth}-$psconf{lmarg}-$psconf{rmarg};
1178
+ my $maxheight = $psconf{pageheight}/3-40;
1179
+ my $width, $height;
1180
+ my $x, $y;
1181
+
1182
+ while ( defined($line = <EPS>) ) {
1183
+ last if ( $line =~ /^%%EOF/ );
1184
+ if ( !defined($bbllx) &&
1185
+ $line =~ /^\%\%BoundingBox\:\s*([0-9\.]+)\s+([0-9\.]+)\s+([0-9\.]+)\s+([0-9\.]+)/i ) {
1186
+ $bbllx = $1+0; $bblly = $2+0;
1187
+ $bburx = $3+0; $bbury = $4+0;
1188
+ }
1189
+ push(@eps,$line);
1190
+ }
1191
+ close(EPS);
1192
+
1193
+ if ( defined($bbllx) ) {
1194
+ $width = $bburx-$bbllx;
1195
+ $height = $bbury-$bblly;
1196
+
1197
+ if ( $width > $maxwidth ) {
1198
+ $scale = $maxwidth/$width;
1199
+ }
1200
+ if ( $height*$scale > $maxheight ) {
1201
+ $scale = $maxheight/$height;
1202
+ }
1203
+
1204
+ $x = ($psconf{pagewidth}-$width*$scale)/2;
1205
+ $y = ($psconf{pageheight}-$height*$scale)/2;
1206
+
1207
+ if ( defined($metadata{logoxadj}) ) {
1208
+ $x += $metadata{logoxadj};
1209
+ }
1210
+ if ( defined($metadata{logoyadj}) ) {
1211
+ $y += $metadata{logoyadj};
1212
+ }
1213
+
1214
+ print "BeginEPSF\n";
1215
+ print $x, ' ', $y, " translate\n";
1216
+ print $scale, " dup scale\n" unless ( $scale == 1 );
1217
+ print -$bbllx, ' ', -$bblly, " translate\n";
1218
+ print "$bbllx $bblly moveto\n";
1219
+ print "$bburx $bblly lineto\n";
1220
+ print "$bburx $bbury lineto\n";
1221
+ print "$bbllx $bbury lineto\n";
1222
+ print "$bbllx $bblly lineto clip newpath\n";
1223
+ print "%%BeginDocument: ",ps_string($metadata{epslogo}),"\n";
1224
+ print @eps;
1225
+ print "%%EndDocument\n";
1226
+ print "EndEPSF\n";
1227
+ }
1228
+ }
1229
+ ps_end_page(0);
1230
+
1231
+ # Emit the rest of the document (page 2 and on)
1232
+ $curpage = 2;
1233
+ ps_start_page();
1234
+ foreach $line ( @pslines ) {
1235
+ my $linfo = $line->[0];
1236
+
1237
+ while ( $$linfo[4] > $curpage ) {
1238
+ ps_end_page($curpage > 2);
1239
+ ps_start_page();
1240
+ $curpage++;
1241
+ }
1242
+
1243
+ print '[';
1244
+ my $curfont = 0;
1245
+ foreach my $c ( @{$line->[1]} ) {
1246
+ if ( $$c[0] >= 0 ) {
1247
+ if ( $curfont != $$c[0] ) {
1248
+ print ($curfont = $$c[0]);
1249
+ }
1250
+ print ps_string($$c[1]);
1251
+ } elsif ( $$c[0] == -1 ) {
1252
+ print '{el}'; # End link
1253
+ } elsif ( $$c[0] == -2 ) {
1254
+ print '{/',$$c[1],' xl}'; # xref link
1255
+ } elsif ( $$c[0] == -3 ) {
1256
+ print '{',ps_string($$c[1]),'wl}'; # web link
1257
+ } elsif ( $$c[0] == -4 ) {
1258
+ # Index anchor -- ignore
1259
+ } elsif ( $$c[0] == -5 ) {
1260
+ print '{/',$$c[1],' xa}'; #xref anchor
1261
+ } elsif ( $$c[0] == -6 ) {
1262
+ print ']['; # Start a new array
1263
+ $curfont = 0;
1264
+ } elsif ( $$c[0] == -7 ) {
1265
+ print '{/',$$c[1],' pl}'; # page link
1266
+ } else {
1267
+ die "Unknown annotation";
1268
+ }
1269
+ }
1270
+ print ']';
1271
+ if ( defined($$linfo[2]) ) {
1272
+ foreach my $x ( @{$$linfo[2]} ) {
1273
+ if ( $$x[0] == $AuxStr ) {
1274
+ print ps_string($$x[1]);
1275
+ } elsif ( $$x[0] == $AuxPage ) {
1276
+ print $ps_xref_page{$$x[1]},' ';
1277
+ } elsif ( $$x[0] == $AuxPageStr ) {
1278
+ print ps_string($ps_xref_page{$$x[1]});
1279
+ } elsif ( $$x[0] == $AuxXRef ) {
1280
+ print '/',ps_xref($$x[1]),' ';
1281
+ } elsif ( $$x[0] == $AuxNum ) {
1282
+ print $$x[1],' ';
1283
+ } else {
1284
+ die "Unknown auxilliary data type";
1285
+ }
1286
+ }
1287
+ }
1288
+ print ($psconf{pageheight}-$psconf{topmarg}-$$linfo[5]);
1289
+ print ' ', $$linfo[6] if ( defined($$linfo[6]) );
1290
+ print ' ', $$linfo[0].$$linfo[1], "\n";
1291
+ }
1292
+
1293
+ ps_end_page(1);
1294
+ print "%%EOF\n";