IOWA 1.0.0

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 (502) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTORS +14 -0
  3. data/README.md +23 -0
  4. data/RELEASE_NOTES +77 -0
  5. data/ToDo +21 -0
  6. data/components/CRUDList/CRUDList.html +13 -0
  7. data/components/CRUDList/CRUDList.iwa +136 -0
  8. data/components/Content/Content.html +0 -0
  9. data/components/Content/Content.iwa +143 -0
  10. data/components/Content/example/README +9 -0
  11. data/components/Content/example/cgi/iowa.cgi +10 -0
  12. data/components/Content/example/demo.rb +30 -0
  13. data/components/Content/example/doc/index.html +7 -0
  14. data/components/Content/example/iowa/Content.html +1 -0
  15. data/components/Content/example/iowa/Content.iwa +1 -0
  16. data/components/Content/example/iowa/Main.html +6 -0
  17. data/components/Content/example/iowa/Main.iwa +3 -0
  18. data/components/Content/example/iowa/_content/body +7 -0
  19. data/components/Content/example/iowa/_content/body2 +3 -0
  20. data/components/Content/example/iowa/_content/title +2 -0
  21. data/components/Content/example/iowa/app.cnf +8 -0
  22. data/components/Content/example/iowa/app.rb +8 -0
  23. data/components/Content/example/webrick.rb +38 -0
  24. data/components/Include/Include.html +1 -0
  25. data/components/Include/Include.iwa +30 -0
  26. data/components/Include/readme +5 -0
  27. data/components/JumpTo/JumpTo.html +8 -0
  28. data/components/JumpTo/JumpTo.iwa +8 -0
  29. data/components/JumpTo/readme +6 -0
  30. data/doc/Architecture.txt +6 -0
  31. data/doc/History.txt +33 -0
  32. data/doc/StandardDispatcher.txt +19 -0
  33. data/examples/blog/README +1 -0
  34. data/examples/hello_world/README +17 -0
  35. data/examples/hello_world/htdocs/hello_world_html.html +24 -0
  36. data/examples/hello_world/htdocs/hello_world_ruby.html +41 -0
  37. data/examples/hello_world/iowa/HelloWorld.html +14 -0
  38. data/examples/hello_world/iowa/HelloWorld.iwa +31 -0
  39. data/examples/hello_world/iowa/Index.html +16 -0
  40. data/examples/hello_world/iowa/Index.iwa +5 -0
  41. data/examples/hello_world/iowa/iowa_hello_world.cnf +19 -0
  42. data/examples/hello_world/iowa/iowa_hello_world.rb +5 -0
  43. data/examples/hello_world/iowa/mapfile.cnf +6 -0
  44. data/examples/hw1/iowa/Main.html +1 -0
  45. data/examples/hw1/iowa/README +9 -0
  46. data/examples/hw1/iowa/hw.rb +4 -0
  47. data/examples/hw2/iowa/Main.html +10 -0
  48. data/examples/hw2/iowa/Main.iwa +7 -0
  49. data/examples/hw2/iowa/README +16 -0
  50. data/examples/hw2/iowa/hw.rb +4 -0
  51. data/examples/hw3/iowa/Main.html +11 -0
  52. data/examples/hw3/iowa/Main.iwa +7 -0
  53. data/examples/hw3/iowa/README +22 -0
  54. data/examples/hw3/iowa/hw.rb +4 -0
  55. data/examples/hw4/iowa/Greetings.html +10 -0
  56. data/examples/hw4/iowa/Greetings.iwa +9 -0
  57. data/examples/hw4/iowa/Main.html +12 -0
  58. data/examples/hw4/iowa/Main.iwa +10 -0
  59. data/examples/hw4/iowa/README +28 -0
  60. data/examples/hw4/iowa/hw.rb +4 -0
  61. data/examples/hw5/iowa/Footer.html +2 -0
  62. data/examples/hw5/iowa/Greetings.html +4 -0
  63. data/examples/hw5/iowa/Greetings.iwa +12 -0
  64. data/examples/hw5/iowa/Header.html +6 -0
  65. data/examples/hw5/iowa/Main.html +12 -0
  66. data/examples/hw5/iowa/Main.iwa +13 -0
  67. data/examples/hw5/iowa/README +16 -0
  68. data/examples/hw5/iowa/hw.rb +4 -0
  69. data/examples/template_server/iowa/Content.iwa +121 -0
  70. data/examples/template_server/iowa/Content.view +0 -0
  71. data/examples/template_server/iowa/DBContentDispatcher.rb +112 -0
  72. data/examples/template_server/iowa/DBContentPage.html +3 -0
  73. data/examples/template_server/iowa/DBContentPage.iwa +85 -0
  74. data/examples/template_server/iowa/app.cnf +13 -0
  75. data/examples/template_server/iowa/app.rb +5 -0
  76. data/ext/Classifier/classifier.c +256 -0
  77. data/ext/Classifier/ext_help.h +14 -0
  78. data/ext/Classifier/extconf.rb +5 -0
  79. data/ext/Classifier/tst.h +40 -0
  80. data/ext/Classifier/tst_cleanup.c +24 -0
  81. data/ext/Classifier/tst_delete.c +146 -0
  82. data/ext/Classifier/tst_grow_node_free_list.c +38 -0
  83. data/ext/Classifier/tst_init.c +41 -0
  84. data/ext/Classifier/tst_insert.c +192 -0
  85. data/ext/Classifier/tst_search.c +68 -0
  86. data/ext/http11/README +11 -0
  87. data/ext/http11/ext_help.h +15 -0
  88. data/ext/http11/extconf.rb +5 -0
  89. data/ext/http11/http11.c +534 -0
  90. data/ext/http11/http11.c.dif +422 -0
  91. data/ext/http11/http11_parser.c +1243 -0
  92. data/ext/http11/http11_parser.c.dif +193 -0
  93. data/ext/http11/http11_parser.h +49 -0
  94. data/ext/http11/http11_parser.h.dif +20 -0
  95. data/ext/http11/http11_parser.rl +192 -0
  96. data/ext/httpmachine/Makefile +149 -0
  97. data/ext/httpmachine/extconf.rb +33 -0
  98. data/ext/httpmachine/http.cpp +430 -0
  99. data/ext/httpmachine/http.h +156 -0
  100. data/ext/httpmachine/rubyhttp.cpp +165 -0
  101. data/external/mime-types/LICENCE +18 -0
  102. data/external/mime-types/README +46 -0
  103. data/external/mime-types/doc/classes/MIME.html +120 -0
  104. data/external/mime-types/doc/classes/MIME/InvalidContentType.html +119 -0
  105. data/external/mime-types/doc/classes/MIME/Type.html +866 -0
  106. data/external/mime-types/doc/classes/MIME/Type.src/M000010.html +22 -0
  107. data/external/mime-types/doc/classes/MIME/Type.src/M000011.html +18 -0
  108. data/external/mime-types/doc/classes/MIME/Type.src/M000012.html +19 -0
  109. data/external/mime-types/doc/classes/MIME/Type.src/M000013.html +18 -0
  110. data/external/mime-types/doc/classes/MIME/Type.src/M000014.html +26 -0
  111. data/external/mime-types/doc/classes/MIME/Type.src/M000015.html +33 -0
  112. data/external/mime-types/doc/classes/MIME/Type.src/M000016.html +27 -0
  113. data/external/mime-types/doc/classes/MIME/Type.src/M000017.html +35 -0
  114. data/external/mime-types/doc/classes/MIME/Type.src/M000018.html +34 -0
  115. data/external/mime-types/doc/classes/MIME/Type.src/M000019.html +24 -0
  116. data/external/mime-types/doc/classes/MIME/Type.src/M000020.html +38 -0
  117. data/external/mime-types/doc/classes/MIME/Type.src/M000021.html +22 -0
  118. data/external/mime-types/doc/classes/MIME/Type.src/M000022.html +18 -0
  119. data/external/mime-types/doc/classes/MIME/Type.src/M000023.html +18 -0
  120. data/external/mime-types/doc/classes/MIME/Type.src/M000024.html +18 -0
  121. data/external/mime-types/doc/classes/MIME/Type.src/M000025.html +18 -0
  122. data/external/mime-types/doc/classes/MIME/Type.src/M000026.html +18 -0
  123. data/external/mime-types/doc/classes/MIME/Type.src/M000027.html +18 -0
  124. data/external/mime-types/doc/classes/MIME/Type.src/M000028.html +18 -0
  125. data/external/mime-types/doc/classes/MIME/Type.src/M000029.html +18 -0
  126. data/external/mime-types/doc/classes/MIME/Type.src/M000030.html +19 -0
  127. data/external/mime-types/doc/classes/MIME/Type.src/M000031.html +26 -0
  128. data/external/mime-types/doc/classes/MIME/Types.html +459 -0
  129. data/external/mime-types/doc/classes/MIME/Types.src/M000001.html +19 -0
  130. data/external/mime-types/doc/classes/MIME/Types.src/M000002.html +32 -0
  131. data/external/mime-types/doc/classes/MIME/Types.src/M000003.html +21 -0
  132. data/external/mime-types/doc/classes/MIME/Types.src/M000004.html +18 -0
  133. data/external/mime-types/doc/classes/MIME/Types.src/M000005.html +26 -0
  134. data/external/mime-types/doc/classes/MIME/Types.src/M000006.html +18 -0
  135. data/external/mime-types/doc/classes/MIME/Types.src/M000007.html +18 -0
  136. data/external/mime-types/doc/classes/MIME/Types.src/M000008.html +18 -0
  137. data/external/mime-types/doc/classes/MIME/Types.src/M000009.html +18 -0
  138. data/external/mime-types/doc/created.rid +1 -0
  139. data/external/mime-types/doc/files/ChangeLog.html +320 -0
  140. data/external/mime-types/doc/files/README.html +145 -0
  141. data/external/mime-types/doc/files/lib/mime/types_rb.html +101 -0
  142. data/external/mime-types/doc/fr_class_index.html +30 -0
  143. data/external/mime-types/doc/fr_file_index.html +29 -0
  144. data/external/mime-types/doc/fr_method_index.html +57 -0
  145. data/external/mime-types/doc/index.html +24 -0
  146. data/external/mime-types/doc/rdoc-style.css +208 -0
  147. data/external/mime-types/lib/mime/types.rb +1558 -0
  148. data/external/package.rb +672 -0
  149. data/external/test_support.rb +95 -0
  150. data/external/tmail/README +7 -0
  151. data/external/tmail/tmail.rb +4 -0
  152. data/external/tmail/tmail/address.rb +222 -0
  153. data/external/tmail/tmail/base64.rb +52 -0
  154. data/external/tmail/tmail/compat.rb +39 -0
  155. data/external/tmail/tmail/config.rb +50 -0
  156. data/external/tmail/tmail/encode.rb +447 -0
  157. data/external/tmail/tmail/header.rb +895 -0
  158. data/external/tmail/tmail/info.rb +14 -0
  159. data/external/tmail/tmail/loader.rb +1 -0
  160. data/external/tmail/tmail/mail.rb +869 -0
  161. data/external/tmail/tmail/mailbox.rb +386 -0
  162. data/external/tmail/tmail/mbox.rb +1 -0
  163. data/external/tmail/tmail/net.rb +260 -0
  164. data/external/tmail/tmail/obsolete.rb +123 -0
  165. data/external/tmail/tmail/parser.rb +1475 -0
  166. data/external/tmail/tmail/parser.y +372 -0
  167. data/external/tmail/tmail/port.rb +356 -0
  168. data/external/tmail/tmail/scanner.rb +17 -0
  169. data/external/tmail/tmail/scanner_r.rb +243 -0
  170. data/external/tmail/tmail/stringio.rb +256 -0
  171. data/external/tmail/tmail/textutils.rb +197 -0
  172. data/external/tmail/tmail/tmail.rb +1 -0
  173. data/external/tmail/tmail/utils.rb +23 -0
  174. data/external/win32-process/README +133 -0
  175. data/external/win32-process/lib/win32/process.rb +561 -0
  176. data/external/windows-pr/README +145 -0
  177. data/external/windows-pr/doc/conversion_guide.txt +25 -0
  178. data/external/windows-pr/lib/windows/clipboard.rb +72 -0
  179. data/external/windows-pr/lib/windows/console.rb +323 -0
  180. data/external/windows-pr/lib/windows/device_io.rb +88 -0
  181. data/external/windows-pr/lib/windows/directory.rb +80 -0
  182. data/external/windows-pr/lib/windows/error.rb +313 -0
  183. data/external/windows-pr/lib/windows/eventlog.rb +120 -0
  184. data/external/windows-pr/lib/windows/file.rb +349 -0
  185. data/external/windows-pr/lib/windows/filesystem.rb +16 -0
  186. data/external/windows-pr/lib/windows/handle.rb +31 -0
  187. data/external/windows-pr/lib/windows/library.rb +76 -0
  188. data/external/windows-pr/lib/windows/limits.rb +13 -0
  189. data/external/windows-pr/lib/windows/memory.rb +117 -0
  190. data/external/windows-pr/lib/windows/msvcrt/buffer.rb +48 -0
  191. data/external/windows-pr/lib/windows/msvcrt/file.rb +18 -0
  192. data/external/windows-pr/lib/windows/msvcrt/string.rb +46 -0
  193. data/external/windows-pr/lib/windows/national.rb +557 -0
  194. data/external/windows-pr/lib/windows/path.rb +296 -0
  195. data/external/windows-pr/lib/windows/pipe.rb +77 -0
  196. data/external/windows-pr/lib/windows/process.rb +171 -0
  197. data/external/windows-pr/lib/windows/registry.rb +238 -0
  198. data/external/windows-pr/lib/windows/security.rb +89 -0
  199. data/external/windows-pr/lib/windows/service.rb +183 -0
  200. data/external/windows-pr/lib/windows/shell.rb +88 -0
  201. data/external/windows-pr/lib/windows/sound.rb +52 -0
  202. data/external/windows-pr/lib/windows/synchronize.rb +161 -0
  203. data/external/windows-pr/lib/windows/system_info.rb +70 -0
  204. data/external/windows-pr/lib/windows/unicode.rb +138 -0
  205. data/external/windows-pr/lib/windows/window.rb +22 -0
  206. data/iowa.gemspec +45 -0
  207. data/microprojects/DiskCache/LICENSE +28 -0
  208. data/microprojects/DiskCache/README +17 -0
  209. data/microprojects/DiskCache/external/package.rb +608 -0
  210. data/microprojects/DiskCache/external/test_support.rb +8 -0
  211. data/microprojects/DiskCache/setup.rb +22 -0
  212. data/microprojects/DiskCache/src/iowa/Association.rb +67 -0
  213. data/microprojects/DiskCache/src/iowa/Constants.rb +159 -0
  214. data/microprojects/DiskCache/src/iowa/DiskStore.rb +377 -0
  215. data/microprojects/DiskCache/src/iowa/Hash.rb +63 -0
  216. data/microprojects/DiskCache/src/iowa/Lockfile.rb +575 -0
  217. data/microprojects/DiskCache/src/iowa/Mutex.rb +142 -0
  218. data/microprojects/DiskCache/src/iowa/caches/DiskCache.rb +605 -0
  219. data/microprojects/DiskCache/src/iowa/caches/LRUCache.rb +287 -0
  220. data/microprojects/DiskCache/test/TC_DiskCache.rb +218 -0
  221. data/microprojects/LRUCache/LICENSE +28 -0
  222. data/microprojects/LRUCache/README +13 -0
  223. data/microprojects/LRUCache/external/package.rb +608 -0
  224. data/microprojects/LRUCache/external/test_support.rb +8 -0
  225. data/microprojects/LRUCache/setup.rb +22 -0
  226. data/microprojects/LRUCache/src/iowa/Association.rb +57 -0
  227. data/microprojects/LRUCache/src/iowa/Constants.rb +159 -0
  228. data/microprojects/LRUCache/src/iowa/Hash.rb +63 -0
  229. data/microprojects/LRUCache/src/iowa/Mutex.rb +129 -0
  230. data/microprojects/LRUCache/src/iowa/caches/LRUCache.rb +287 -0
  231. data/microprojects/LRUCache/test/TC_LRUCache.rb +65 -0
  232. data/microprojects/LinkedList/LICENSE +28 -0
  233. data/microprojects/LinkedList/README +13 -0
  234. data/microprojects/LinkedList/external/package.rb +608 -0
  235. data/microprojects/LinkedList/external/test_support.rb +8 -0
  236. data/microprojects/LinkedList/setup.rb +22 -0
  237. data/microprojects/LinkedList/src/iowa/LinkedList.rb +165 -0
  238. data/microprojects/LinkedList/test/TC_LinkedList.rb +42 -0
  239. data/microprojects/README +8 -0
  240. data/setup.rb +116 -0
  241. data/share/iowa/app_skeleton/Main.html +8 -0
  242. data/share/iowa/app_skeleton/Main.iwa +15 -0
  243. data/share/iowa/app_skeleton/app.cnf +48 -0
  244. data/share/iowa/app_skeleton/app.rb +58 -0
  245. data/share/iowa/app_skeleton/models/model.rb +49 -0
  246. data/src/ihc.rb +223 -0
  247. data/src/iowa.cgi +29 -0
  248. data/src/iowa.rb +637 -0
  249. data/src/iowa/AbstractCache.rb +96 -0
  250. data/src/iowa/AcceptLanguage.rb +76 -0
  251. data/src/iowa/Application.rb +928 -0
  252. data/src/iowa/ApplicationStats.rb +72 -0
  253. data/src/iowa/Association.rb +67 -0
  254. data/src/iowa/BindingsParser.rb +62 -0
  255. data/src/iowa/Breakpoint.rb +273 -0
  256. data/src/iowa/CSS.rb +564 -0
  257. data/src/iowa/Client.rb +192 -0
  258. data/src/iowa/Component.rb +405 -0
  259. data/src/iowa/ComponentProxy.rb +26 -0
  260. data/src/iowa/Config.rb +21 -0
  261. data/src/iowa/Constants.rb +226 -0
  262. data/src/iowa/Context.rb +218 -0
  263. data/src/iowa/ContextLogger.rb +16 -0
  264. data/src/iowa/DbPool.rb +222 -0
  265. data/src/iowa/DetachedComponent.rb +18 -0
  266. data/src/iowa/Dispatcher.rb +27 -0
  267. data/src/iowa/DynamicElements.rb +471 -0
  268. data/src/iowa/Element.rb +100 -0
  269. data/src/iowa/Email.rb +287 -0
  270. data/src/iowa/Extensions/AllExtensions.rb +4 -0
  271. data/src/iowa/Extensions/Class.rb +94 -0
  272. data/src/iowa/Extensions/Date.rb +88 -0
  273. data/src/iowa/Extensions/DateTime.rb +88 -0
  274. data/src/iowa/Extensions/Hash.rb +22 -0
  275. data/src/iowa/Extensions/Kernel.rb +6 -0
  276. data/src/iowa/Extensions/Numeric.rb +47 -0
  277. data/src/iowa/Extensions/Object.rb +11 -0
  278. data/src/iowa/Extensions/String.rb +60 -0
  279. data/src/iowa/Extensions/Time.rb +89 -0
  280. data/src/iowa/Extensions/TimeExtensions.rb +6 -0
  281. data/src/iowa/Form.rb +368 -0
  282. data/src/iowa/Hash.rb +85 -0
  283. data/src/iowa/ISAAC.rb +175 -0
  284. data/src/iowa/ImageSize.rb +279 -0
  285. data/src/iowa/IowaComponentMixins.rb +7 -0
  286. data/src/iowa/JSON-lexer.rb +296 -0
  287. data/src/iowa/JSON-objects.rb +201 -0
  288. data/src/iowa/KeyValueCoding.rb +91 -0
  289. data/src/iowa/LinkedList.rb +175 -0
  290. data/src/iowa/Loader.rb +22 -0
  291. data/src/iowa/Lockfile.rb +575 -0
  292. data/src/iowa/Logger.rb +74 -0
  293. data/src/iowa/Monkey.rb +20 -0
  294. data/src/iowa/Mutex.rb +142 -0
  295. data/src/iowa/Policy.rb +70 -0
  296. data/src/iowa/Pool.rb +243 -0
  297. data/src/iowa/PrettyException.rb +1091 -0
  298. data/src/iowa/Request.rb +244 -0
  299. data/src/iowa/Response.rb +133 -0
  300. data/src/iowa/Session.rb +354 -0
  301. data/src/iowa/SessionStats.rb +78 -0
  302. data/src/iowa/String.rb +65 -0
  303. data/src/iowa/Tag.rb +101 -0
  304. data/src/iowa/TemplateParser.rb +236 -0
  305. data/src/iowa/Util.rb +314 -0
  306. data/src/iowa/Webcache.rb +122 -0
  307. data/src/iowa/caches/BiLevelCache.rb +65 -0
  308. data/src/iowa/caches/ClassLimitedCache.rb +67 -0
  309. data/src/iowa/caches/DiskCache.rb +609 -0
  310. data/src/iowa/caches/DiskStore.rb +380 -0
  311. data/src/iowa/caches/LRUCache-alternative.rb +155 -0
  312. data/src/iowa/caches/LRUCache.rb +290 -0
  313. data/src/iowa/caches/SimpleLRUCache.rb +112 -0
  314. data/src/iowa/dispatchers/StandardDispatcher.rb +396 -0
  315. data/src/iowa/dispatchers/StandardDispatcherWithClassifier.rb +93 -0
  316. data/src/iowa/js/iowa_jsonrpc.js +381 -0
  317. data/src/iowa/js/jsonrpc.js +187 -0
  318. data/src/iowa/js/jsonrpc_async.js +261 -0
  319. data/src/iowa/loaders/DiskLoader.rb +50 -0
  320. data/src/iowa/loggers/Analogger.rb +54 -0
  321. data/src/iowa/loggers/AsyncLogger.rb +54 -0
  322. data/src/iowa/loggers/BitBucket.rb +38 -0
  323. data/src/iowa/loggers/Log4R.rb +13 -0
  324. data/src/iowa/loggers/Log4rLogger.rb +48 -0
  325. data/src/iowa/loggers/Logger.rb +29 -0
  326. data/src/iowa/loggers/RubyLogger.rb +9 -0
  327. data/src/iowa/pools/DBConnectionPool.rb +53 -0
  328. data/src/iowa/request/Apache.rb +90 -0
  329. data/src/iowa/request/EMHybrid.rb +59 -0
  330. data/src/iowa/request/ENV.rb +80 -0
  331. data/src/iowa/request/FCGI.rb +68 -0
  332. data/src/iowa/request/HTTPMachine.rb +75 -0
  333. data/src/iowa/request/Mongrel.rb +68 -0
  334. data/src/iowa/request/WEBrick.rb +48 -0
  335. data/src/iowa/version.rb +3 -0
  336. data/src/iowa/webrick/HTTPServer.rb +43 -0
  337. data/src/iowa/webrick/WEBrickServlet.rb +28 -0
  338. data/src/iowa_fcgi_handler.rb +101 -0
  339. data/src/iowa_httpmachine.rb +141 -0
  340. data/src/iowa_hybrid.rb +193 -0
  341. data/src/iowa_hybrid_cluster.rb +231 -0
  342. data/src/iowa_mongrel.rb +136 -0
  343. data/src/iowa_webrick.rb +194 -0
  344. data/src/iowa_webrick_legacy.rb +104 -0
  345. data/src/mod_iowa.rb +104 -0
  346. data/tcss.rb +61 -0
  347. data/test/README.windows +12 -0
  348. data/test/TC_AcceptLanguage.rb +61 -0
  349. data/test/TC_AppConfig.rb +43 -0
  350. data/test/TC_AppConfig/cgi/iowa.cgi +7 -0
  351. data/test/TC_AppConfig/doc/index.html +1 -0
  352. data/test/TC_AppConfig/iowa/Main.html +4 -0
  353. data/test/TC_AppConfig/iowa/Main.iwa +17 -0
  354. data/test/TC_AppConfig/iowa/README +1 -0
  355. data/test/TC_AppConfig/iowa/app.cnf +19 -0
  356. data/test/TC_AppConfig/iowa/app.rb +8 -0
  357. data/test/TC_AppConfig/webrick.rb +38 -0
  358. data/test/TC_Association.rb +29 -0
  359. data/test/TC_BiLevelCache.rb +71 -0
  360. data/test/TC_CGI_Adaptor.rb +55 -0
  361. data/test/TC_CGI_Adaptor/cgi/iowa.cgi +7 -0
  362. data/test/TC_CGI_Adaptor/doc/index.html +1 -0
  363. data/test/TC_CGI_Adaptor/iowa/Main.html +8 -0
  364. data/test/TC_CGI_Adaptor/iowa/Main.iwa +14 -0
  365. data/test/TC_CGI_Adaptor/iowa/README +1 -0
  366. data/test/TC_CGI_Adaptor/iowa/app.cnf +8 -0
  367. data/test/TC_CGI_Adaptor/iowa/app.rb +8 -0
  368. data/test/TC_CGI_Adaptor/webrick.rb +38 -0
  369. data/test/TC_CSS.rb +660 -0
  370. data/test/TC_ClassLimitedCache.rb +89 -0
  371. data/test/TC_Classifier.rb +80 -0
  372. data/test/TC_DbPool.rb +127 -0
  373. data/test/TC_DiskCache.rb +218 -0
  374. data/test/TC_Hybrid.rb +58 -0
  375. data/test/TC_Hybrid/doc/thing.txt +1 -0
  376. data/test/TC_Hybrid/iowa/Main.html +3 -0
  377. data/test/TC_Hybrid/iowa/Main.iwa +7 -0
  378. data/test/TC_Hybrid/iowa/NewPage.html +1 -0
  379. data/test/TC_Hybrid/iowa/NewPage.iwa +5 -0
  380. data/test/TC_Hybrid/iowa/app.cnf +10 -0
  381. data/test/TC_Hybrid/iowa/app.rb +5 -0
  382. data/test/TC_IOWAFunctions/doc/Ajax1.html +1 -0
  383. data/test/TC_IOWAFunctions/doc/Ajax1.iwa +1 -0
  384. data/test/TC_IOWAFunctions/doc/index.html +1 -0
  385. data/test/TC_IOWAFunctions/doc/js/dojo.js +9686 -0
  386. data/test/TC_IOWAFunctions/iowa/Ajax1.html +40 -0
  387. data/test/TC_IOWAFunctions/iowa/Ajax1.iwa +23 -0
  388. data/test/TC_IOWAFunctions/iowa/AjaxWidget.iwa +19 -0
  389. data/test/TC_IOWAFunctions/iowa/AjaxWidget.view +22 -0
  390. data/test/TC_IOWAFunctions/iowa/DanielTest.html +9 -0
  391. data/test/TC_IOWAFunctions/iowa/DanielTest.iwa +10 -0
  392. data/test/TC_IOWAFunctions/iowa/IntervalWidget.html +1 -0
  393. data/test/TC_IOWAFunctions/iowa/IntervalWidget.iwa +14 -0
  394. data/test/TC_IOWAFunctions/iowa/Main.html +1 -0
  395. data/test/TC_IOWAFunctions/iowa/NestedRepeat1.html +12 -0
  396. data/test/TC_IOWAFunctions/iowa/NestedRepeat1.iwa +24 -0
  397. data/test/TC_IOWAFunctions/iowa/RPCResponse.iwa +7 -0
  398. data/test/TC_IOWAFunctions/iowa/RPCResponse.view +1 -0
  399. data/test/TC_IOWAFunctions/iowa/Repeat1.iwa +31 -0
  400. data/test/TC_IOWAFunctions/iowa/Repeat1.view +9 -0
  401. data/test/TC_IOWAFunctions/iowa/Repeat2.iwa +32 -0
  402. data/test/TC_IOWAFunctions/iowa/Repeat2.view +11 -0
  403. data/test/TC_IOWAFunctions/iowa/Repeat3.iwa +44 -0
  404. data/test/TC_IOWAFunctions/iowa/Repeat3.view +18 -0
  405. data/test/TC_IOWAFunctions/iowa/TesCon.html +1 -0
  406. data/test/TC_IOWAFunctions/iowa/TesCon.iwa +5 -0
  407. data/test/TC_IOWAFunctions/iowa/app.cnf +19 -0
  408. data/test/TC_IOWAFunctions/iowa/app.rb +9 -0
  409. data/test/TC_IOWAFunctions/iowa/mapfile.cnf +8 -0
  410. data/test/TC_ISAAC.rb +52 -0
  411. data/test/TC_ImageSize.rb +84 -0
  412. data/test/TC_ImageSize/img.bmp +0 -0
  413. data/test/TC_ImageSize/img.gif +0 -0
  414. data/test/TC_ImageSize/img.jpg +0 -0
  415. data/test/TC_ImageSize/img.pcx +0 -0
  416. data/test/TC_ImageSize/img.pgm +7144 -0
  417. data/test/TC_ImageSize/img.png +0 -0
  418. data/test/TC_ImageSize/img.ppm +0 -0
  419. data/test/TC_ImageSize/img.psd +0 -0
  420. data/test/TC_ImageSize/img.tiff +0 -0
  421. data/test/TC_ImageSize/img.xbm +22 -0
  422. data/test/TC_KeyValueCoding.rb +35 -0
  423. data/test/TC_LRUCache.rb +296 -0
  424. data/test/TC_LinkedList.rb +46 -0
  425. data/test/TC_Lockfile.rb +106 -0
  426. data/test/TC_Minimal.rb +45 -0
  427. data/test/TC_Minimal/app.cnf +8 -0
  428. data/test/TC_Minimal/cgi-bin/iowa.cgi +11 -0
  429. data/test/TC_Minimal/doc/index.html +1 -0
  430. data/test/TC_Minimal/iowa/Main.html +1 -0
  431. data/test/TC_Minimal/iowa/README +1 -0
  432. data/test/TC_Minimal/iowa/app.rb +3 -0
  433. data/test/TC_Minimal/webrick.rb +38 -0
  434. data/test/TC_Mongrel.rb +58 -0
  435. data/test/TC_Mongrel/doc/thing.txt +1 -0
  436. data/test/TC_Mongrel/iowa/Main.html +3 -0
  437. data/test/TC_Mongrel/iowa/Main.iwa +7 -0
  438. data/test/TC_Mongrel/iowa/NewPage.html +1 -0
  439. data/test/TC_Mongrel/iowa/NewPage.iwa +5 -0
  440. data/test/TC_Mongrel/iowa/app.cnf +10 -0
  441. data/test/TC_Mongrel/iowa/app.rb +5 -0
  442. data/test/TC_NoSubclass.rb +56 -0
  443. data/test/TC_NoSubclass/cgi/iowa.cgi +7 -0
  444. data/test/TC_NoSubclass/doc/index.html +1 -0
  445. data/test/TC_NoSubclass/iowa/Main.html +8 -0
  446. data/test/TC_NoSubclass/iowa/Main.iwa +14 -0
  447. data/test/TC_NoSubclass/iowa/README +1 -0
  448. data/test/TC_NoSubclass/iowa/app.cnf +8 -0
  449. data/test/TC_NoSubclass/iowa/app.rb +5 -0
  450. data/test/TC_NoSubclass/webrick.rb +38 -0
  451. data/test/TC_Pool.rb +139 -0
  452. data/test/TC_RenderedCache/doc/thing.txt +1 -0
  453. data/test/TC_RenderedCache/iowa/BigPage.html +1 -0
  454. data/test/TC_RenderedCache/iowa/BigPage.iwa +12 -0
  455. data/test/TC_RenderedCache/iowa/Main.html +3 -0
  456. data/test/TC_RenderedCache/iowa/Main.iwa +7 -0
  457. data/test/TC_RenderedCache/iowa/NewPage.html +1 -0
  458. data/test/TC_RenderedCache/iowa/NewPage.iwa +11 -0
  459. data/test/TC_RenderedCache/iowa/app.cnf +13 -0
  460. data/test/TC_RenderedCache/iowa/app.rb +5 -0
  461. data/test/TC_RenderedCache/iowa/mapfile.map +4 -0
  462. data/test/TC_ResourceURL.rb +73 -0
  463. data/test/TC_ResourceURL/iowa/Main.html +2 -0
  464. data/test/TC_ResourceURL/iowa/Main.iwa +10 -0
  465. data/test/TC_ResourceURL/iowa/app.cnf +10 -0
  466. data/test/TC_ResourceURL/iowa/app.rb +5 -0
  467. data/test/TC_SimpleDetached.rb +41 -0
  468. data/test/TC_StandardDispatcher.rb +362 -0
  469. data/test/TC_StandardDispatcherWithClassifier.rb +358 -0
  470. data/test/TC_String.rb +24 -0
  471. data/test/TC_Tag.rb +41 -0
  472. data/test/TC_Webrick.rb +56 -0
  473. data/test/TC_Webrick/doc/thing.txt +1 -0
  474. data/test/TC_Webrick/iowa/Main.html +3 -0
  475. data/test/TC_Webrick/iowa/Main.iwa +7 -0
  476. data/test/TC_Webrick/iowa/NewPage.html +1 -0
  477. data/test/TC_Webrick/iowa/NewPage.iwa +5 -0
  478. data/test/TC_Webrick/iowa/app.cnf +10 -0
  479. data/test/TC_Webrick/iowa/app.rb +5 -0
  480. data/test/tc_template.rb +15 -0
  481. data/test/tests.conf +19 -0
  482. data/utils/CVS/Entries +3 -0
  483. data/utils/CVS/Repository +1 -0
  484. data/utils/CVS/Root +1 -0
  485. data/utils/QuickCert-1.0.2.tar.gz +0 -0
  486. data/utils/QuickCert-1.0.2/InstalledFiles +7 -0
  487. data/utils/QuickCert-1.0.2/MANIFEST +10 -0
  488. data/utils/QuickCert-1.0.2/Makefile +15 -0
  489. data/utils/QuickCert-1.0.2/README +56 -0
  490. data/utils/QuickCert-1.0.2/bin/QuickCert +355 -0
  491. data/utils/QuickCert-1.0.2/config.save +12 -0
  492. data/utils/QuickCert-1.0.2/data/examples/ruby/QuickCert/README +60 -0
  493. data/utils/QuickCert-1.0.2/data/examples/ruby/QuickCert/drbssl_c.rb +26 -0
  494. data/utils/QuickCert-1.0.2/data/examples/ruby/QuickCert/drbssl_s.rb +35 -0
  495. data/utils/QuickCert-1.0.2/data/examples/ruby/QuickCert/qc_config +21 -0
  496. data/utils/QuickCert-1.0.2/lib/QuickCert/defaults.rb +28 -0
  497. data/utils/QuickCert-1.0.2/setup.rb +1312 -0
  498. data/utils/iowa_apps +422 -0
  499. data/utils/smtp_sink.rb +9 -0
  500. data/utils/startup_template.cnf +27 -0
  501. data/utils/startup_template.rb +73 -0
  502. metadata +551 -0
@@ -0,0 +1,1091 @@
1
+ ###################################################
2
+ # Original Author:: Dmitry V. Sabanin <sdmitry@lrn.ru>
3
+ # License:: LGPL
4
+ #
5
+ # Modified for IOWA by Kirk Haines
6
+ ###################################################
7
+
8
+ if RUBY_VERSION !~ /^1\.8/
9
+ require 'rdoc'
10
+ end
11
+ require 'rbconfig'
12
+
13
+ ###################################################
14
+ # Web PrettyPrint for Exceptions
15
+ #
16
+ module Iowa
17
+
18
+ class PrettyException
19
+
20
+ attr_writer :message
21
+
22
+ ###################################################
23
+ def initialize(exception, tplpath = nil)
24
+ @tplpath = tplpath
25
+ @exception = exception
26
+ @message = nil
27
+ end
28
+ ###################################################
29
+
30
+ ###################################################
31
+ def build_template
32
+ tmpl =
33
+ if @tplpath and File.exists?(@tplpath)
34
+ File.read(@tplpath)
35
+ else
36
+ tplfile = File.readlines(__FILE__)
37
+ start = nil
38
+ tplfile.each_with_index do |line,idx|
39
+ if line =~ /^__END__\s*$/
40
+ start = idx + 1
41
+ break
42
+ end
43
+ end
44
+ tplfile[start..-1].join('')
45
+ end
46
+
47
+ return TemplatePage.new(tmpl)
48
+ end
49
+ ###################################################
50
+
51
+ ###################################################
52
+ def gen_source(file, line, mark_line = true)
53
+ source = File.readlines(file)
54
+ source = hilite_source(source)
55
+ line = line.to_i
56
+ if mark_line
57
+ show = 3
58
+ begin_from = line - show
59
+ end_at = line + show
60
+ begin_from = begin_from > 0 ? begin_from : 0
61
+ work_with = source[begin_from..end_at]
62
+ else
63
+ work_with = [ source[line-1] ]
64
+ end
65
+ work_with ||= []
66
+ res = []
67
+ work_with.each do |i, l|
68
+ l = ('<span class="hl_lineno">%.3d:</span>%s' % [i," "]) + l
69
+ if i == line and mark_line
70
+ buf = '<div class="current_line">' + l + '</div>'
71
+ else
72
+ buf = l + "\n"
73
+ end
74
+ res << buf
75
+ end
76
+ res.join
77
+ end
78
+ ###################################################
79
+
80
+ ###################################################
81
+ def hilite_source(src)
82
+ lx = LexerRuby::LexerOld.new
83
+ src.each do |sline|
84
+ lx.lex_line(sline)
85
+ end
86
+ res = []
87
+ lineno = 0
88
+ this_line = []
89
+ hc = false
90
+ heredoc_buf = nil
91
+ lx.result.each do |text, token|
92
+ if hc
93
+ lineno += 1
94
+ res << [lineno, this_line.join]
95
+ this_line = []
96
+ hc = false
97
+ end
98
+ if token != :heredoc and heredoc_buf and token != :any
99
+ heredoc = heredoc_buf.split(/\n/)
100
+ heredoc.each do |hd_line|
101
+ res << [lineno, ('<span class="hl_heredoc">%s</span>' % [hd_line.to_s])]
102
+ lineno += 1
103
+ end
104
+ this_line = []
105
+ heredoc_buf = nil
106
+ end
107
+ case token
108
+ when :keyword, :ident, :punct,
109
+ :comment, :ivar, :dot,
110
+ :string, :command, :number,
111
+ :gvar, :literal, :symbol
112
+ if token == :comment
113
+ hc = true
114
+ end
115
+ text = Iowa::Util.escapeHTML(text)
116
+ this_line << ('<span class="hl_%s">%s</span>' % [token.to_s, text.rstrip])
117
+ when :heredoc
118
+ text = Iowa::Util.escapeHTML(text)
119
+ heredoc_buf ||= ''
120
+ heredoc_buf << text
121
+ when :any
122
+ if text =~ /^\s*\n$/
123
+ lineno += 1
124
+ res << [lineno, this_line.join]
125
+ this_line = []
126
+ else
127
+ this_line << text
128
+ end
129
+ else
130
+ this_line << Iowa::Util.escapeHTML(text)
131
+ end
132
+ end
133
+ res << [lineno+1, this_line.join] if this_line.length > 0
134
+ res
135
+ end
136
+ ###################################################
137
+
138
+ ###################################################
139
+ def print
140
+ tpl = build_template
141
+ contents = {}
142
+ contents['message'] = Iowa::Util::escapeHTML(@exception.message).to_s
143
+ contents['exception'] = @exception.class.name
144
+ contents['time'] = Time.now.to_s
145
+ bt = []
146
+ @exception.backtrace.each_with_index do |str,idx|
147
+ file,text = str.scan(/^(.+):(.+)(?::(.+))?$/).flatten;
148
+ file,line = file.split(/:/)
149
+ unless line
150
+ line = text
151
+ text = nil
152
+ end
153
+ is_stdlib = false
154
+ paths = [RbConfig::CONFIG['rubylibdir'], RbConfig::CONFIG['sitedir']]
155
+ paths.each do |dir|
156
+ is_stdlib = true if (file =~ /#{Regexp::escape(dir)}/)
157
+ end
158
+ data = { 'file' => file, 'line' => line, 'text' => text, 'from_stdlib' => false}
159
+ if idx == 0
160
+ data['source'] = file == '(eval)' ? '' : gen_source(file, line)
161
+ else
162
+ data['source'] = file == '(eval)' ? '' : gen_source(file, line)
163
+ end
164
+ data['iteration_id'] = idx.to_s
165
+ bt << data
166
+ end
167
+ contents['backtrace'] = bt
168
+ tpl.write_html_on(output='', contents)
169
+ output
170
+ end
171
+ ###################################################
172
+
173
+ alias_method :to_s, :print
174
+
175
+ end
176
+ end
177
+
178
+ class LexerBase
179
+ def initialize
180
+ @states = []
181
+ @result = []
182
+ @result_endofline = nil
183
+ end
184
+ attr_reader :states, :result, :result_endofline
185
+
186
+ def set_states(states)
187
+ @states = states
188
+ end
189
+ def set_result(result)
190
+ @result = result
191
+ end
192
+ def format(text, state_output)
193
+ @result << [text, state_output]
194
+ end
195
+ def format_end(state_output)
196
+ @result_endofline = state_output
197
+ end
198
+ def match(regexp, output)
199
+ m = regexp.match(@text)
200
+ return false unless m
201
+ txt = @text.slice!(0, m.end(0))
202
+ format(txt, output)
203
+ true
204
+ end
205
+ def lex_line(text)
206
+ raise "derived class #{self.class} must overload #lex_line."
207
+ end
208
+ def self.profile
209
+ lines = IO.readlines(__FILE__)
210
+ lexer = self.new
211
+ puts "profiling the #{self.inspect} lexer (this may take some time)"
212
+ require 'profiler'
213
+ Profiler__.start_profile
214
+ lines.each do |line|
215
+ lexer.set_states([])
216
+ lexer.set_result([])
217
+ lexer.lex_line(line)
218
+ end
219
+ Profiler__.print_profile(STDOUT)
220
+ end
221
+ def self.benchmark
222
+ n = 10000
223
+ puts "benchmarking the lexers (computing #{n} lines " +
224
+ "with GC disabled)"
225
+ require 'benchmark'
226
+ Benchmark.bm(20) do |b|
227
+ lexer = LexerRuby::LexerOld.new
228
+ #=begin
229
+ lines = IO.readlines(__FILE__)
230
+ GC.disable
231
+ b.report("#{lexer.class}") do
232
+ n.times do |i|
233
+ lexer.set_states([])
234
+ lexer.set_result([])
235
+ lexer.lex_line(lines[i%lines.size].clone)
236
+ end
237
+ end
238
+ #=begin
239
+ GC.enable
240
+ GC.start
241
+ lines = IO.readlines(__FILE__)
242
+ lexer = LexerRuby::LexerNew.new
243
+ GC.disable
244
+ b.report("#{lexer.class}") do
245
+ n.times do |i|
246
+ lexer.set_states([])
247
+ lexer.set_result([])
248
+ lexer.lex_line(lines[i%lines.size])
249
+ end
250
+ end
251
+ =begin
252
+ =end
253
+ GC.enable
254
+ GC.start
255
+ lines = IO.readlines(__FILE__)
256
+ lexer = LexerRuby::Lexer3.new
257
+ GC.disable
258
+ b.report("#{lexer.class}") do
259
+ n.times do |i|
260
+ lexer.set_states([])
261
+ lexer.set_result([])
262
+ lexer.lex_line(lines[i%lines.size])
263
+ end
264
+ end
265
+ GC.enable
266
+ end
267
+ end
268
+ end
269
+
270
+ module LexerText
271
+
272
+ class Lexer < LexerBase
273
+ RE_TAB = /\A\t+/
274
+ RE_NOTTAB = /\A[^\t]+/
275
+ def lex_line(text)
276
+ @text = text
277
+ until @text.empty?
278
+ if match(RE_TAB, :tab)
279
+ else
280
+ match(RE_NOTTAB, :text)
281
+ end
282
+ end
283
+ end
284
+ end # class Lexer
285
+
286
+ end # module LexerText
287
+
288
+ module LexerRuby
289
+
290
+ module State
291
+
292
+ class Base
293
+ end
294
+
295
+ class Heredoc < Base
296
+ def initialize(begin_tag, ignore_leading_spaces, interpolate=true)
297
+ @begin_tag = begin_tag
298
+ @ignore_leading_spaces = ignore_leading_spaces
299
+ @interpolate = interpolate
300
+ end
301
+ attr_reader :begin_tag, :ignore_leading_spaces, :interpolate
302
+ def ==(other)
303
+ (self.class == other.class) and
304
+ (@begin_tag == other.begin_tag) and
305
+ (@ignore_leading_spaces == other.ignore_leading_spaces) and
306
+ (@interpolate == other.interpolate)
307
+ end
308
+ end
309
+
310
+ class Comment < Base
311
+ def ==(other)
312
+ (self.class == other.class)
313
+ end
314
+ end
315
+
316
+ class Endoffile < Base
317
+ def ==(other)
318
+ (self.class == other.class)
319
+ end
320
+ end
321
+
322
+ end # module State
323
+
324
+ class NewerRubyLexer
325
+ RE_TOKENIZE = Regexp.new([
326
+ # TODO: @ivar
327
+ # TODO: @@cvar
328
+ # TODO: $gvar
329
+ # TODO: %literals %w(a b c) %Q|'"|
330
+ # TODO: :symbol
331
+ # TODO: ?x chars
332
+ # TODO: 0b01001 binary data
333
+ # TODO: 0x234af hex data
334
+ # TODO: keywords =begin defined?
335
+ # TODO: ruby puncturation .. ... && ||
336
+ # TODO: /regexp/
337
+ # TODO: __END__ tag
338
+ # TODO: illegal ruby heredoc which has space after end-tag
339
+ # TODO: illegal ruby puncturation &&& |||
340
+ # TODO: illegal ruby numbers 0x23Yab
341
+ '#.*', # # blah ## !?! comment
342
+ '<<-?[[:alpha:]]+', # <<HTML <<-XML heredoc
343
+ '<<-?\'[[:alpha:]]+\'', # <<'eof' <<-'X' heredoc single quoted
344
+ '<<-?"[[:alpha:]]+"', # <<"eof" <<-"X" heredoc double quoted
345
+ '\.[[:alpha:]][[:alnum:]_]*', # .method .dup2 method call
346
+ '[[:alpha:]][[:alnum:]_]*', # value pix2_3 identifier
347
+ '\'(?:[^\\\\]|\\\\.)*?\'', # '\'x\\' '' string single quoted
348
+ '"(?:[^\\\\]|\\\\.)*?"', # "ab" "" string double quoted
349
+ '\d+\.\d+', # 0.123 32.10 number as float
350
+ '\d+', # 42 999 number as integer
351
+ '.' # * + fallthrough
352
+ ].join('|'))
353
+ def initialize
354
+ @char_to_symbol_hash = {
355
+ " " => :space,
356
+ "\t" => :tab
357
+ }
358
+ @char_to_symbol_hash.default = :should_not_happen
359
+ end
360
+ def tokenize(string)
361
+ string.scan(RE_TOKENIZE)
362
+ end
363
+ def lex(string)
364
+ tokens = tokenize(string)
365
+ states = tokens.map do |token|
366
+ # TODO: by inserting 2 parentesises in the TOKENIZER
367
+ # then I can destinguish between good/bad tokens.
368
+ # 'ab'.scan(/(a)(b)/) do |(good, bad)|
369
+ case token
370
+ when /\A(?:"|')./
371
+ :string
372
+ when /\A<<-?(?:"|'|)[[:alpha:]]/
373
+ :heredoc
374
+ when /\A\.[[:alpha:]]/
375
+ :method
376
+ when /\A[[:alpha:]]/
377
+ :ident
378
+ when /\A#/
379
+ :comment
380
+ when /\A[[:punct:]]/
381
+ :punct
382
+ when /\A[[:digit:]]/
383
+ :number
384
+ else
385
+ @char_to_symbol_hash[token]
386
+ end
387
+ end
388
+ [tokens, states]
389
+ end
390
+ end
391
+
392
+ class Lexer3 < LexerBase
393
+ def initialize
394
+ @rl = NewerRubyLexer.new
395
+ super
396
+ end
397
+ def what_to_output(hash)
398
+ @rl.what_to_output(hash)
399
+ end
400
+ def lex_line(text)
401
+ tokens, states = @rl.lex(text)
402
+ tokens.each_with_index do |token, index|
403
+ format(token, states[index])
404
+ end
405
+ true
406
+ end
407
+ end
408
+
409
+
410
+ class RubyLexer
411
+ def initialize
412
+ @result = []
413
+ end
414
+ attr_reader :result
415
+ PUNCT = ['(', ')'] +
416
+ %w(=== == =~ => = != !~ !) +
417
+ %w(<< <=> <= < >= >) +
418
+ %w({ } [ ]) +
419
+ %w(:: : ... ..) +
420
+ %w(+= + -= - ** * / %) +
421
+ %w(|| | && &) +
422
+ %w(, ;)
423
+ RE_NUMBER = /\d[\d\.]*/
424
+ RE_PUNCT = Regexp.new('(?:' +
425
+ PUNCT.map{|i| Regexp.escape(i)}.join('|') + ')')
426
+ RE_IDENT = /[[:alpha:]][\w\!]*/
427
+ RE_STRING = /".*?"|'.*?'/
428
+ RE_COMMENT = /#.*/
429
+ RE_COMMAND = /\.[[:alnum:]_]*[[:alnum:]_\?\!]/
430
+ RE_SPACE = /\x20+/
431
+ RE_NEWLINE = /\n+/
432
+ RE_TABS = /\t+/
433
+ def scan_index(string, regexp, prio, symbol)
434
+ string.scan(regexp) do
435
+ @result << [$~.begin(0), prio, $~.end(0), symbol]
436
+ end
437
+ end
438
+ def lex(string)
439
+ scan_index(string, RE_COMMENT, 0, :comment)
440
+ scan_index(string, RE_STRING, 1, :string)
441
+ scan_index(string, RE_COMMAND, 2, :command)
442
+ scan_index(string, RE_IDENT, 3, :ident)
443
+ scan_index(string, RE_NUMBER, 4, :number)
444
+ scan_index(string, RE_PUNCT, 5, :punct)
445
+ scan_index(string, RE_SPACE, 6, :space)
446
+ scan_index(string, RE_NEWLINE, 7, :newline)
447
+ scan_index(string, RE_TABS, 8, :tabs)
448
+ end
449
+
450
+ remove_method(:result)
451
+ def result
452
+ # primary key = string begin position
453
+ # secondary key = priority
454
+ @result.sort!
455
+ # collect the highest precedens data
456
+ ary = [0]
457
+ @result.each do |i1, prio, i2, symbol|
458
+ next if ary.last > i1 # discard low precedens data
459
+ if ary.last < i1
460
+ ary << :any
461
+ ary << i1
462
+ end
463
+ ary << symbol
464
+ ary << i2
465
+ end
466
+ #p ary
467
+ ary
468
+ end
469
+ def self.mk(*symbols)
470
+ symbols.each do |symbol|
471
+ class_eval %{
472
+ def #{symbol.to_s}
473
+ res = []
474
+ @result.each do |i1, prio, i2, sym|
475
+ if sym == :#{symbol.to_s}
476
+ res << [i1, i2]
477
+ end
478
+ end
479
+ res
480
+ end
481
+ }
482
+ end
483
+ end
484
+ mk :number, :ident, :string, :punct
485
+ mk :comment, :command, :space, :newline, :tabs
486
+ end
487
+
488
+ class LexerNew < LexerBase
489
+ def lex_line(text)
490
+ #puts("-"*40)
491
+ #puts "text=#{text.inspect}"
492
+ rl = RubyLexer.new
493
+ rl.lex(text)
494
+ res = rl.result
495
+ #puts "res=#{res.inspect}"
496
+ i1 = res.shift
497
+ while res.size > 1
498
+ symbol = res.shift
499
+ i2 = res.shift
500
+ format(text[i1, (i2-i1)], symbol)
501
+ i1 = i2
502
+ end
503
+ #puts "result=#{@result.inspect}"
504
+ true
505
+ end
506
+ end
507
+
508
+ class LexerOld < LexerBase
509
+ RE_COMMENT = /^#.*/m
510
+
511
+ RE_TAB = /^\t+/
512
+
513
+ RE_SPACE = /^\x20+/
514
+
515
+ KEYWORDS = %w(alias and begin BEGIN break case class) +
516
+ %w(defined? def do else elsif end END ensure for if loop) +
517
+ %w(module next nil not or raise redo require rescue) +
518
+ %w(retry return self super then true false undef) +
519
+ %w(unless until yield when while)
520
+ RE_KEYWORD = Regexp.new(
521
+ '\A(?:' +
522
+ KEYWORDS.map{|txt|Regexp.escape(txt)}.join('|') +
523
+ ')(?!\w)'
524
+ )
525
+
526
+ RE_SYMBOL = /\A:[[:alpha:]_][[:alnum:]_]*/
527
+
528
+ RE_STRING = /^("|\')(?:[^\\]|\\.)*?\1/
529
+ RE_STRING_INTERPOL = /\A ((?:[^\\]|\\.)*?) (\#\{ .*? \}) /x
530
+ # TODO: interpolated code can nest (hint: recursion is necessary)
531
+ def match_string
532
+ m = RE_STRING.match(@text)
533
+ return false unless m
534
+ txt = @text.slice!(0, m.end(0))
535
+ if m[1] == '\''
536
+ format(txt, :string)
537
+ return true
538
+ end
539
+ # double quoted strings may contain interpolated code
540
+ until txt.empty?
541
+ m = RE_STRING_INTERPOL.match(txt)
542
+ unless m
543
+ format(txt, :string)
544
+ break
545
+ end
546
+ format(m[1], :string) unless m[1].empty?
547
+ format(m[2], :string1)
548
+ txt.slice!(0, m.end(0))
549
+ end
550
+ true
551
+ end
552
+
553
+ RE_REGEXP = /\A\/(.*?[^\\])?\//
554
+
555
+ RE_IVAR = /\A@[[:alnum:]_]+/
556
+
557
+ RE_DOT = /\A\.[[:alnum:]_]*[[:alnum:]_\?\!]/
558
+
559
+ RE_IDENTIFIER = /\A(?:[[:alnum:]_]+|\S+)/
560
+
561
+ RE_NUMBER = Regexp.new(
562
+ '\A(?:' + [
563
+ '0x[_a-fA-F0-9]+',
564
+ '0b[_01]+',
565
+ '\d[0-9_]*(?:\.[0-9_]*)?',
566
+ '\?.'
567
+ ].join('|') +
568
+ ')'
569
+ )
570
+
571
+ PUNCT = ['(', ')'] +
572
+ %w(=== == =~ => = != !~ !) +
573
+ %w(<< <=> <= < >= >) +
574
+ %w({ } [ ]) +
575
+ %w(:: : ... ..) +
576
+ %w(+= + -= - ** * / %) +
577
+ %w(|| | && &) +
578
+ %w(, ;)
579
+ RE_PUNCT = Regexp.new(
580
+ '\A(?:' +
581
+ PUNCT.map{|txt|Regexp.escape(txt)}.join('|') +
582
+ ')'
583
+ )
584
+
585
+ VAR_GLOBALS = %q(_~*$!@/\\;,.=:<>"-&`'+1234567890).split(//)
586
+ RE_GVAR = Regexp.new(
587
+ '\A\$(?:' +
588
+ VAR_GLOBALS.map{|txt|Regexp.escape(txt)}.join('|') +
589
+ '|[[:alnum:]_]+' +
590
+ ')'
591
+ )
592
+
593
+ # TODO: deal with multiline literals
594
+ RE_LITERAL = Regexp.new(
595
+ '\A%[Qqwrx]?(?:' + [
596
+ '\(.*?\)', # TODO: must count pairs
597
+ '\{.*?\}', # TODO: must count pairs
598
+ '\<.*?\>', # TODO: must count pairs
599
+ '\[.*?\]', # TODO: must count pairs
600
+ '([^\(\{\<\[]).*?\1'
601
+ ].join('|') + ')'
602
+ )
603
+
604
+ RE_BEGIN = /\A=begin$\n?\x20*\z/ # eat tailing space
605
+ def match_comment_begin
606
+ m = RE_BEGIN.match(@text)
607
+ return false unless m
608
+ #puts "comments"
609
+ @states << State::Comment.new
610
+ txt = @text.slice!(0, m.end(0))
611
+ format(txt, :mcomment)
612
+ format_end(:mcomment_end)
613
+ true
614
+ end
615
+ RE_HEREDOC = /\A<<(-)?('|"|)(\w+)\2/
616
+ def match_heredoc_begin
617
+ m = RE_HEREDOC.match(@text)
618
+ return false unless m
619
+ ignore_leading_space = (!m[1].nil?)
620
+ interpolate = (m[2] != "'")
621
+ begin_pattern = m[3]
622
+ @states << State::Heredoc.new(
623
+ begin_pattern,
624
+ ignore_leading_space,
625
+ interpolate
626
+ )
627
+ txt = @text.slice!(0, m.end(0))
628
+ format(txt, :heredoc)
629
+ true
630
+ end
631
+ RE_END = /\A__END__$\n?\x20*\z/ # eat tailing space
632
+ def match_endoffile
633
+ m = RE_END.match(@text)
634
+ return false unless m
635
+ #puts "propagate __END__"
636
+ @states << State::Endoffile.new
637
+ txt = @text.slice!(0, m.end(0))
638
+ format(txt, :endoffile)
639
+ format_end(:endoffile_end)
640
+ true
641
+ end
642
+ def lex_line_normal(text)
643
+ @text = text
644
+ return if match_comment_begin
645
+ return if match_endoffile
646
+ until @text.empty?
647
+ if match(RE_COMMENT, :comment)
648
+ format_end(:comment_end)
649
+ elsif match(RE_REGEXP, :regexp)
650
+ elsif match_heredoc_begin
651
+ elsif match(RE_LITERAL, :literal)
652
+ elsif match(RE_KEYWORD, :keyword)
653
+ elsif match(RE_SYMBOL, :symbol)
654
+ elsif match(RE_PUNCT, :punct)
655
+ elsif match(RE_GVAR, :gvar)
656
+ elsif match_string
657
+ elsif match(RE_NUMBER, :number)
658
+ elsif match(RE_IVAR, :ivar)
659
+ elsif match(RE_DOT, :dot)
660
+ elsif match(RE_IDENTIFIER, :ident)
661
+ elsif match(RE_TAB, :tab)
662
+ elsif match(RE_SPACE, :space)
663
+ else
664
+ #@text.slice!(0, 1)
665
+ txt = @text.slice!(0, 1)
666
+ format(txt, :any)
667
+ end
668
+ end
669
+ end
670
+ def match_heredoc_end(regexp)
671
+ m = regexp.match(@text)
672
+ return false unless m
673
+ #puts "end of heredoc"
674
+ @states.shift
675
+ txt = @text.slice!(0, m.end(0))
676
+ format(txt, :heredoc)
677
+ format_end(:heredoc_end2)
678
+ true
679
+ end
680
+ def lex_line_heredoc(text)
681
+ # TODO: color interpolated code #{code}
682
+ @text = text
683
+ format_end(:heredoc_end)
684
+ hd_end = nil
685
+ state = @states[0]
686
+ hd_end = /\A#{state.begin_tag}$\n?\x20*\z/
687
+ return if match_heredoc_end(hd_end)
688
+ # continue lexing
689
+ ign_lead_spc = state.ignore_leading_spaces
690
+ until @text.empty?
691
+ if match(RE_TAB, :heredoc_tab)
692
+ elsif ign_lead_spc and match_heredoc_end(hd_end)
693
+ else
694
+ txt = @text.slice!(0, 1)
695
+ format(txt, :heredoc)
696
+ end
697
+ end
698
+ end
699
+ def match_comment_end
700
+ m = /\A\=end\b.*?$\n?\x20*\z/.match(@text)
701
+ return false unless m
702
+ #puts "comment end"
703
+ @states.shift
704
+ txt = @text.slice!(0, m.end(0))
705
+ format(txt, :mcomment)
706
+ true
707
+ end
708
+ def lex_line_comment(text)
709
+ @text = text
710
+ format_end(:mcomment_end)
711
+ return if match_comment_end
712
+ until @text.empty?
713
+ if match(RE_TAB, :mcomment_tab)
714
+ else
715
+ txt = @text.slice!(0, 1)
716
+ format(txt, :mcomment)
717
+ end
718
+ end
719
+ end
720
+ def lex_line_endoffile(text)
721
+ @text = text
722
+ format_end(:endoffile_end)
723
+ until @text.empty?
724
+ if match(RE_TAB, :endoffile_tab)
725
+ else
726
+ txt = @text.slice!(0, 1)
727
+ format(txt, :endoffile)
728
+ end
729
+ end
730
+ end
731
+ def lex_line(text)
732
+ if @states.empty?
733
+ return lex_line_normal(text)
734
+ end
735
+ state = @states[0]
736
+ case state
737
+ when State::Heredoc
738
+ lex_line_heredoc(text)
739
+ when State::Comment
740
+ lex_line_comment(text)
741
+ when State::Endoffile
742
+ lex_line_endoffile(text)
743
+ else
744
+ raise "unknown state #{state.class}"
745
+ end
746
+ end
747
+ end
748
+
749
+ # TODO: make the new lexer work!
750
+ Lexer = LexerOld # slow
751
+ #Lexer = LexerNew # slow
752
+ #Lexer = Lexer3 # fastest
753
+
754
+ end # module LexerRuby
755
+
756
+ __END__
757
+ <html>
758
+ <head>
759
+ <title>Oops!</title>
760
+ <style>
761
+ .data {
762
+ border-style: dotted;
763
+ padding: 4px; }
764
+ .trace_header {
765
+ border-style: dotted;
766
+ border-width: thin;
767
+ background-color: #CCCCCC;
768
+ text-align: center; }
769
+ .normal_trace_entry {
770
+ border-style: dotted;
771
+ border-width: thin;
772
+ text-align: center;
773
+ padding: 6px; }
774
+ .stdlib_trace_entry {
775
+ border-style: dotted;
776
+ border-width: thin;
777
+ text-align: right;
778
+ padding: 6px; }
779
+ .source {
780
+ width: 100%;
781
+ background-color: #F4F4F4;
782
+ display: none;
783
+ }
784
+ span.hl_lineno {
785
+ font-weight: bold;
786
+ }
787
+ pre {
788
+ width: 80%;
789
+ padding: 0px;
790
+ margin: 0px;
791
+ }
792
+ div.current_line {
793
+ color: red;
794
+ background-color: #F4DADA;
795
+ }
796
+ span.hl_keyword {
797
+ font-weight: bold;
798
+ }
799
+ span.hl_punct {
800
+ font-weight: bold;
801
+ color: darkblue;
802
+ }
803
+ span.hl_ident {
804
+ }
805
+ span.hl_command {
806
+ font-weight: bold;
807
+ }
808
+ span.hl_number {
809
+ color: darkgreen;
810
+ }
811
+ span.hl_string {
812
+ color: darkgreen;
813
+ }
814
+ span.hl_comment {
815
+ color: grey;
816
+ }
817
+ span.hl_ivar {
818
+ font-weight: bold;
819
+ color: darkred;
820
+ }
821
+ span.hl_dot {
822
+ font-weight: bold;
823
+ }
824
+ span.hl_literal {
825
+ color: green;
826
+ }
827
+ span.hl_gvar {
828
+ font-weight: bold;
829
+ }
830
+ span.hl_symbol {
831
+ color: blue;
832
+ }
833
+ span.hl_regexp {
834
+ color: green;
835
+ }
836
+ tr {
837
+ background-color: white;
838
+ }
839
+ </style>
840
+ <script type="text/javascript" language="javascript">
841
+ function toggleCode( id ) {
842
+ if ( document.getElementById )
843
+ elem = document.getElementById( id );
844
+ else if ( document.all )
845
+ elem = eval( "document.all." + id );
846
+ else
847
+ return false;
848
+
849
+ elemStyle = elem.style;
850
+
851
+ if ( elemStyle.display != "block" ) {
852
+ elemStyle.display = "block"
853
+ } else {
854
+ elemStyle.display = "none"
855
+ }
856
+
857
+ return true;
858
+ }
859
+
860
+ var isDOM = (typeof(document.getElementsByTagName) != 'undefined'
861
+ && typeof(document.createElement) != 'undefined')
862
+ ? 1 : 0;
863
+ var isIE4 = (typeof(document.all) != 'undefined'
864
+ && parseInt(navigator.appVersion) >= 4)
865
+ ? 1 : 0;
866
+ var isNS4 = (typeof(document.layers) != 'undefined')
867
+ ? 1 : 0;
868
+ var capable = (isDOM || isIE4 || isNS4)
869
+ ? 1 : 0;
870
+ // Uggly fix for Opera and Konqueror 2.2 that are half DOM compliant
871
+ if (capable) {
872
+ if (typeof(window.opera) != 'undefined') {
873
+ var browserName = ' ' + navigator.userAgent.toLowerCase();
874
+ if ((browserName.indexOf('konqueror 7') == 0)) {
875
+ capable = 0;
876
+ }
877
+ } else if (typeof(navigator.userAgent) != 'undefined') {
878
+ var browserName = ' ' + navigator.userAgent.toLowerCase();
879
+ if ((browserName.indexOf('konqueror') > 0) && (browserName.indexOf('konqueror/3') == 0)) {
880
+ capable = 0;
881
+ }
882
+ } // end if... else if...
883
+ } // end if
884
+
885
+ /**
886
+ * This array is used to remember mark status of rows in browse mode
887
+ */
888
+ var marked_row = new Array;
889
+
890
+
891
+ /**
892
+ * Sets/unsets the pointer and marker in browse mode
893
+ *
894
+ * @param object the table row
895
+ * @param integer the row number
896
+ * @param string the action calling this script (over, out or click)
897
+ * @param string the default background color
898
+ * @param string the color to use for mouseover
899
+ * @param string the color to use for marking a row
900
+ *
901
+ * @return boolean whether pointer is set or not
902
+ */
903
+ function setPointer(theRow, theRowNum, theAction, theDefaultColor, thePointerColor, theMarkColor)
904
+ {
905
+ var theCells = null;
906
+
907
+ // 1. Pointer and mark feature are disabled or the browser can't get the
908
+ // row -> exits
909
+ if ((thePointerColor == '' && theMarkColor == '')
910
+ || typeof(theRow.style) == 'undefined') {
911
+ return false;
912
+ }
913
+
914
+ // 2. Gets the current row and exits if the browser can't get it
915
+ if (typeof(document.getElementsByTagName) != 'undefined') {
916
+ theCells = theRow.getElementsByTagName('td');
917
+ }
918
+ else if (typeof(theRow.cells) != 'undefined') {
919
+ theCells = theRow.cells;
920
+ }
921
+ else {
922
+ return false;
923
+ }
924
+
925
+ // 3. Gets the current color...
926
+ var rowCellsCnt = theCells.length;
927
+ var domDetect = null;
928
+ var currentColor = null;
929
+ var newColor = null;
930
+ // 3.1 ... with DOM compatible browsers except Opera that does not return
931
+ // valid values with "getAttribute"
932
+ if (typeof(window.opera) == 'undefined'
933
+ && typeof(theCells[0].getAttribute) != 'undefined') {
934
+ currentColor = theCells[0].getAttribute('bgcolor');
935
+ domDetect = true;
936
+ }
937
+ // 3.2 ... with other browsers
938
+ else {
939
+ currentColor = theCells[0].style.backgroundColor;
940
+ domDetect = false;
941
+ } // end 3
942
+
943
+ // 3.3 ... Opera changes colors set via HTML to rgb(r,g,b) format so fix it
944
+ if (currentColor.indexOf("rgb") >= 0)
945
+ {
946
+ var rgbStr = currentColor.slice(currentColor.indexOf('(') + 1,
947
+ currentColor.indexOf(')'));
948
+ var rgbValues = rgbStr.split(",");
949
+ currentColor = "#";
950
+ var hexChars = "0123456789ABCDEF";
951
+ for (var i = 0; i < 3; i++)
952
+ {
953
+ var v = rgbValues[i].valueOf();
954
+ currentColor += hexChars.charAt(v/16) + hexChars.charAt(v%16);
955
+ }
956
+ }
957
+
958
+ // 4. Defines the new color
959
+ // 4.1 Current color is the default one
960
+ if (currentColor == ''
961
+ || currentColor.toLowerCase() == theDefaultColor.toLowerCase()) {
962
+ if (theAction == 'over' && thePointerColor != '') {
963
+ newColor = thePointerColor;
964
+ }
965
+ else if (theAction == 'click' && theMarkColor != '') {
966
+ newColor = theMarkColor;
967
+ marked_row[theRowNum] = true;
968
+ // Garvin: deactivated onclick marking of the checkbox because it's also executed
969
+ // when an action (like edit/delete) on a single item is performed. Then the checkbox
970
+ // would get deactived, even though we need it activated. Maybe there is a way
971
+ // to detect if the row was clicked, and not an item therein...
972
+ // document.getElementById('id_rows_to_delete' + theRowNum).checked = true;
973
+ }
974
+ }
975
+ // 4.1.2 Current color is the pointer one
976
+ else if (currentColor.toLowerCase() == thePointerColor.toLowerCase()
977
+ && (typeof(marked_row[theRowNum]) == 'undefined' || !marked_row[theRowNum])) {
978
+ if (theAction == 'out') {
979
+ newColor = theDefaultColor;
980
+ }
981
+ else if (theAction == 'click' && theMarkColor != '') {
982
+ newColor = theMarkColor;
983
+ marked_row[theRowNum] = true;
984
+ // document.getElementById('id_rows_to_delete' + theRowNum).checked = true;
985
+ }
986
+ }
987
+ // 4.1.3 Current color is the marker one
988
+ else if (currentColor.toLowerCase() == theMarkColor.toLowerCase()) {
989
+ if (theAction == 'click') {
990
+ newColor = (thePointerColor != '')
991
+ ? thePointerColor
992
+ : theDefaultColor;
993
+ marked_row[theRowNum] = (typeof(marked_row[theRowNum]) == 'undefined' || !marked_row[theRowNum])
994
+ ? true
995
+ : null;
996
+ // document.getElementById('id_rows_to_delete' + theRowNum).checked = false;
997
+ }
998
+ } // end 4
999
+
1000
+ // 5. Sets the new color...
1001
+ if (newColor) {
1002
+ var c = null;
1003
+ // 5.1 ... with DOM compatible browsers except Opera
1004
+ if (domDetect) {
1005
+ for (c = 0; c < rowCellsCnt; c++) {
1006
+ theCells[c].setAttribute('bgcolor', newColor, 0);
1007
+ } // end for
1008
+ }
1009
+ // 5.2 ... with other browsers
1010
+ else {
1011
+ for (c = 0; c < rowCellsCnt; c++) {
1012
+ theCells[c].style.backgroundColor = newColor;
1013
+ }
1014
+ }
1015
+ } // end 5
1016
+
1017
+ return true;
1018
+ } // end of the 'setPointer()' function
1019
+
1020
+
1021
+ /**
1022
+ * getElement
1023
+ */
1024
+ function getElement(e,f){
1025
+ if(document.layers){
1026
+ f=(f)?f:self;
1027
+ if(f.document.layers[e]) {
1028
+ return f.document.layers[e];
1029
+ }
1030
+ for(W=0;i<f.document.layers.length;W++) {
1031
+ return(getElement(e,fdocument.layers[W]));
1032
+ }
1033
+ }
1034
+ if(document.all) {
1035
+ return document.all[e];
1036
+ }
1037
+ return document.getElementById(e);
1038
+ }
1039
+ </script>
1040
+ </head>
1041
+ <body bgcolor="white">
1042
+ <table cellspacing="4" width ="80%" align="center">
1043
+ <tr>
1044
+ <td colspan="3" align="left" class="normal_trace_entry">
1045
+ <p class="data" style="font-size: large; margin: 0px; border-color: red;"><b>Exception raised!</b><br />
1046
+ <b>%exception%</b>: <b>%message%</b><br />
1047
+ Time: <b>%time%</b>
1048
+ </p>
1049
+ </td>
1050
+ </tr>
1051
+ <tr>
1052
+ <td class="trace_header"><b>File</b></td>
1053
+ <td class="trace_header"><b>Line</b></td>
1054
+ <td class="trace_header"><b>Info</b></td>
1055
+ </tr>
1056
+ START:backtrace
1057
+ IFNOT:from_stdlib
1058
+ <tr bgcolor="white" onmouseover="setPointer(this, %iteration_id%, 'over', 'white', '#CCFFCC', '#FFB2B2');" onmouseout="setPointer(this, %iteration_id%, 'out', 'white', '#CCFFCC', '#FFB2B2');" onmousedown="toggleCode('src%iteration_id%'); setPointer(this, %iteration_id%, 'click', 'white', '#CCFFCC', '#FFB2B2');">
1059
+ IF:text
1060
+ <td bgcolor="white" class="normal_trace_entry">%file%</td>
1061
+ <td bgcolor="white" class="normal_trace_entry">%line%</td>
1062
+ <td bgcolor="white" class="normal_trace_entry">%text%</td>
1063
+ ENDIF:text
1064
+ IFNOT:text
1065
+ <td bgcolor="white" class="normal_trace_entry">%file%</td>
1066
+ <td bgcolor="white" class="normal_trace_entry" colspan="2">%line%</td>
1067
+ ENDIF:text
1068
+ IF:source
1069
+ </tr>
1070
+ <tr>
1071
+ <td colspan="3"><div id="src%iteration_id%" class="source"><tt><pre>%source%</pre></tt></div></td>
1072
+ ENDIF:source
1073
+ ENDIF:from_stdlib
1074
+ IF:from_stdlib
1075
+ <tr bgcolor="white" onmouseover="setPointer(this, %iteration_id%, 'over', 'white', '#CCFFCC', '#FFB2B2');" onmouseout="setPointer(this, %iteration_id%, 'out', 'white', '#CCFFCC', '#FFB2B2');" onmousedown="setPointer(this, %iteration_id%, 'click', 'white', '#CCFFCC', '#FFB2B2');">
1076
+ IF:text
1077
+ <td bgcolor="white" class="stdlib_trace_entry">%file%</td>
1078
+ <td bgcolor="white" class="stdlib_trace_entry">%line%</td>
1079
+ <td bgcolor="white" class="stdlib_trace_entry">%text%</td>
1080
+ ENDIF:text
1081
+ IFNOT:text
1082
+ <td bgcolor="white" class="stdlib_trace_entry">%file%</td>
1083
+ <td bgcolor="white" class="stdlib_trace_entry" colspan="2">%line%</td>
1084
+ ENDIF:text
1085
+ ENDIF:from_stdlib
1086
+ </tr>
1087
+
1088
+ END:backtrace
1089
+ </table>
1090
+ </body>
1091
+ </html>