enclave 0.1.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 (739) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +182 -0
  3. data/Rakefile +30 -0
  4. data/ext/enclave/enclave.c +390 -0
  5. data/ext/enclave/extconf.rb +33 -0
  6. data/ext/enclave/mruby/Makefile +63 -0
  7. data/ext/enclave/mruby/Rakefile +102 -0
  8. data/ext/enclave/mruby/benchmark/bm_ao_render.rb +309 -0
  9. data/ext/enclave/mruby/benchmark/bm_app_lc_fizzbuzz.rb +51 -0
  10. data/ext/enclave/mruby/benchmark/bm_fib.rb +6 -0
  11. data/ext/enclave/mruby/benchmark/bm_mandel_term.rb +34 -0
  12. data/ext/enclave/mruby/benchmark/bm_so_lists.rb +49 -0
  13. data/ext/enclave/mruby/benchmark/bm_so_mandelbrot.rb +65 -0
  14. data/ext/enclave/mruby/benchmark/vm_dispatch_bench.c +197 -0
  15. data/ext/enclave/mruby/benchmark/vm_optimization_bench.rb +513 -0
  16. data/ext/enclave/mruby/build/host/include/mrbconf.h +230 -0
  17. data/ext/enclave/mruby/build/host/include/mruby/array.h +303 -0
  18. data/ext/enclave/mruby/build/host/include/mruby/boxing_nan.h +169 -0
  19. data/ext/enclave/mruby/build/host/include/mruby/boxing_no.h +59 -0
  20. data/ext/enclave/mruby/build/host/include/mruby/boxing_word.h +248 -0
  21. data/ext/enclave/mruby/build/host/include/mruby/class.h +157 -0
  22. data/ext/enclave/mruby/build/host/include/mruby/common.h +127 -0
  23. data/ext/enclave/mruby/build/host/include/mruby/compile.h +187 -0
  24. data/ext/enclave/mruby/build/host/include/mruby/data.h +76 -0
  25. data/ext/enclave/mruby/build/host/include/mruby/debug.h +75 -0
  26. data/ext/enclave/mruby/build/host/include/mruby/dump.h +159 -0
  27. data/ext/enclave/mruby/build/host/include/mruby/endian.h +44 -0
  28. data/ext/enclave/mruby/build/host/include/mruby/error.h +168 -0
  29. data/ext/enclave/mruby/build/host/include/mruby/gc.h +77 -0
  30. data/ext/enclave/mruby/build/host/include/mruby/hash.h +234 -0
  31. data/ext/enclave/mruby/build/host/include/mruby/internal.h +278 -0
  32. data/ext/enclave/mruby/build/host/include/mruby/irep.h +142 -0
  33. data/ext/enclave/mruby/build/host/include/mruby/istruct.h +50 -0
  34. data/ext/enclave/mruby/build/host/include/mruby/khash.h +455 -0
  35. data/ext/enclave/mruby/build/host/include/mruby/mempool.h +19 -0
  36. data/ext/enclave/mruby/build/host/include/mruby/numeric.h +174 -0
  37. data/ext/enclave/mruby/build/host/include/mruby/object.h +44 -0
  38. data/ext/enclave/mruby/build/host/include/mruby/opcode.h +73 -0
  39. data/ext/enclave/mruby/build/host/include/mruby/ops.h +133 -0
  40. data/ext/enclave/mruby/build/host/include/mruby/presym/id.h +895 -0
  41. data/ext/enclave/mruby/build/host/include/mruby/presym/scanning.h +82 -0
  42. data/ext/enclave/mruby/build/host/include/mruby/presym/table.h +1787 -0
  43. data/ext/enclave/mruby/build/host/include/mruby/presym.h +65 -0
  44. data/ext/enclave/mruby/build/host/include/mruby/proc.h +184 -0
  45. data/ext/enclave/mruby/build/host/include/mruby/range.h +77 -0
  46. data/ext/enclave/mruby/build/host/include/mruby/re.h +16 -0
  47. data/ext/enclave/mruby/build/host/include/mruby/string.h +428 -0
  48. data/ext/enclave/mruby/build/host/include/mruby/throw.h +81 -0
  49. data/ext/enclave/mruby/build/host/include/mruby/value.h +471 -0
  50. data/ext/enclave/mruby/build/host/include/mruby/variable.h +108 -0
  51. data/ext/enclave/mruby/build/host/include/mruby/version.h +143 -0
  52. data/ext/enclave/mruby/build/host/include/mruby.h +1632 -0
  53. data/ext/enclave/mruby/build/host/mrbc/include/mruby/presym/id.h +281 -0
  54. data/ext/enclave/mruby/build/host/mrbc/include/mruby/presym/table.h +559 -0
  55. data/ext/enclave/mruby/build/host/mrbgems/gem_init.c +164 -0
  56. data/ext/enclave/mruby/build/host/mrbgems/mruby-array-ext/gem_init.c +650 -0
  57. data/ext/enclave/mruby/build/host/mrbgems/mruby-binding/gem_init.c +21 -0
  58. data/ext/enclave/mruby/build/host/mrbgems/mruby-catch/gem_init.c +86 -0
  59. data/ext/enclave/mruby/build/host/mrbgems/mruby-class-ext/gem_init.c +21 -0
  60. data/ext/enclave/mruby/build/host/mrbgems/mruby-compar-ext/gem_init.c +99 -0
  61. data/ext/enclave/mruby/build/host/mrbgems/mruby-complex/gem_init.c +362 -0
  62. data/ext/enclave/mruby/build/host/mrbgems/mruby-data/gem_init.c +21 -0
  63. data/ext/enclave/mruby/build/host/mrbgems/mruby-enum-chain/gem_init.c +229 -0
  64. data/ext/enclave/mruby/build/host/mrbgems/mruby-enum-ext/gem_init.c +1420 -0
  65. data/ext/enclave/mruby/build/host/mrbgems/mruby-enum-lazy/gem_init.c +602 -0
  66. data/ext/enclave/mruby/build/host/mrbgems/mruby-enumerator/gem_init.c +822 -0
  67. data/ext/enclave/mruby/build/host/mrbgems/mruby-eval/gem_init.c +21 -0
  68. data/ext/enclave/mruby/build/host/mrbgems/mruby-fiber/gem_init.c +21 -0
  69. data/ext/enclave/mruby/build/host/mrbgems/mruby-hash-ext/gem_init.c +591 -0
  70. data/ext/enclave/mruby/build/host/mrbgems/mruby-kernel-ext/gem_init.c +21 -0
  71. data/ext/enclave/mruby/build/host/mrbgems/mruby-math/gem_init.c +21 -0
  72. data/ext/enclave/mruby/build/host/mrbgems/mruby-metaprog/gem_init.c +21 -0
  73. data/ext/enclave/mruby/build/host/mrbgems/mruby-method/gem_init.c +153 -0
  74. data/ext/enclave/mruby/build/host/mrbgems/mruby-numeric-ext/gem_init.c +211 -0
  75. data/ext/enclave/mruby/build/host/mrbgems/mruby-object-ext/gem_init.c +94 -0
  76. data/ext/enclave/mruby/build/host/mrbgems/mruby-objectspace/gem_init.c +21 -0
  77. data/ext/enclave/mruby/build/host/mrbgems/mruby-pack/gem_init.c +21 -0
  78. data/ext/enclave/mruby/build/host/mrbgems/mruby-proc-binding/gem_init.c +21 -0
  79. data/ext/enclave/mruby/build/host/mrbgems/mruby-proc-ext/gem_init.c +237 -0
  80. data/ext/enclave/mruby/build/host/mrbgems/mruby-random/gem_init.c +21 -0
  81. data/ext/enclave/mruby/build/host/mrbgems/mruby-range-ext/gem_init.c +205 -0
  82. data/ext/enclave/mruby/build/host/mrbgems/mruby-rational/gem_init.c +147 -0
  83. data/ext/enclave/mruby/build/host/mrbgems/mruby-set/gem_init.c +487 -0
  84. data/ext/enclave/mruby/build/host/mrbgems/mruby-sprintf/gem_init.c +83 -0
  85. data/ext/enclave/mruby/build/host/mrbgems/mruby-string-ext/gem_init.c +220 -0
  86. data/ext/enclave/mruby/build/host/mrbgems/mruby-struct/gem_init.c +175 -0
  87. data/ext/enclave/mruby/build/host/mrbgems/mruby-symbol-ext/gem_init.c +153 -0
  88. data/ext/enclave/mruby/build/host/mrbgems/mruby-time/gem_init.c +21 -0
  89. data/ext/enclave/mruby/build/host/mrbgems/mruby-toplevel-ext/gem_init.c +78 -0
  90. data/ext/enclave/mruby/build/host/mrblib/mrblib.c +1758 -0
  91. data/ext/enclave/mruby/build_config/ArduinoDue.rb +72 -0
  92. data/ext/enclave/mruby/build_config/IntelEdison.rb +69 -0
  93. data/ext/enclave/mruby/build_config/IntelGalileo.rb +88 -0
  94. data/ext/enclave/mruby/build_config/RX630.rb +63 -0
  95. data/ext/enclave/mruby/build_config/android_arm64_v8a.rb +11 -0
  96. data/ext/enclave/mruby/build_config/android_armeabi_v7a_neon_hard.rb +13 -0
  97. data/ext/enclave/mruby/build_config/bench.rb +11 -0
  98. data/ext/enclave/mruby/build_config/boxing.rb +19 -0
  99. data/ext/enclave/mruby/build_config/chipKITMax32.rb +68 -0
  100. data/ext/enclave/mruby/build_config/ci/gcc-clang.rb +40 -0
  101. data/ext/enclave/mruby/build_config/ci/msvc.rb +20 -0
  102. data/ext/enclave/mruby/build_config/clang-asan.rb +11 -0
  103. data/ext/enclave/mruby/build_config/cosmopolitan.rb +86 -0
  104. data/ext/enclave/mruby/build_config/cross-32bit.rb +14 -0
  105. data/ext/enclave/mruby/build_config/cross-mingw-winetest.rb +90 -0
  106. data/ext/enclave/mruby/build_config/cross-mingw.rb +14 -0
  107. data/ext/enclave/mruby/build_config/default.rb +83 -0
  108. data/ext/enclave/mruby/build_config/dreamcast_shelf.rb +81 -0
  109. data/ext/enclave/mruby/build_config/emscripten-cxx.rb +12 -0
  110. data/ext/enclave/mruby/build_config/emscripten.rb +10 -0
  111. data/ext/enclave/mruby/build_config/gameboyadvance.rb +72 -0
  112. data/ext/enclave/mruby/build_config/helpers/wine_runner.rb +71 -0
  113. data/ext/enclave/mruby/build_config/host-cxx.rb +12 -0
  114. data/ext/enclave/mruby/build_config/host-debug.rb +20 -0
  115. data/ext/enclave/mruby/build_config/host-f32.rb +14 -0
  116. data/ext/enclave/mruby/build_config/host-gprof.rb +14 -0
  117. data/ext/enclave/mruby/build_config/host-m32.rb +15 -0
  118. data/ext/enclave/mruby/build_config/host-nofloat.rb +22 -0
  119. data/ext/enclave/mruby/build_config/host-shared.rb +36 -0
  120. data/ext/enclave/mruby/build_config/i586-pc-msdosdjgpp.rb +76 -0
  121. data/ext/enclave/mruby/build_config/luckfox_pico.rb +106 -0
  122. data/ext/enclave/mruby/build_config/milkv_duo.rb +106 -0
  123. data/ext/enclave/mruby/build_config/minimal.rb +4 -0
  124. data/ext/enclave/mruby/build_config/mrbc.rb +10 -0
  125. data/ext/enclave/mruby/build_config/nintendo_switch.rb +73 -0
  126. data/ext/enclave/mruby/build_config/nintendo_wii.rb +95 -0
  127. data/ext/enclave/mruby/build_config/no-float.rb +17 -0
  128. data/ext/enclave/mruby/build_config/playstationportable.rb +78 -0
  129. data/ext/enclave/mruby/build_config/serenity.rb +26 -0
  130. data/ext/enclave/mruby/build_config.rb +9 -0
  131. data/ext/enclave/mruby/examples/mrbgems/c_and_ruby_extension_example/mrblib/example.rb +5 -0
  132. data/ext/enclave/mruby/examples/mrbgems/c_and_ruby_extension_example/src/example.c +23 -0
  133. data/ext/enclave/mruby/examples/mrbgems/c_and_ruby_extension_example/test/example.rb +7 -0
  134. data/ext/enclave/mruby/examples/mrbgems/c_extension_example/src/example.c +23 -0
  135. data/ext/enclave/mruby/examples/mrbgems/c_extension_example/test/example.c +7 -0
  136. data/ext/enclave/mruby/examples/mrbgems/c_extension_example/test/example.rb +3 -0
  137. data/ext/enclave/mruby/examples/mrbgems/cdata_extension_example/src/example.c +77 -0
  138. data/ext/enclave/mruby/examples/mrbgems/cdata_extension_example/test/example.c +7 -0
  139. data/ext/enclave/mruby/examples/mrbgems/mruby-YOUR-bigint/core/bigint.c +70 -0
  140. data/ext/enclave/mruby/examples/mrbgems/ruby_extension_example/mrblib/example.rb +5 -0
  141. data/ext/enclave/mruby/examples/mrbgems/ruby_extension_example/test/example.rb +3 -0
  142. data/ext/enclave/mruby/include/mrbconf.h +230 -0
  143. data/ext/enclave/mruby/include/mruby/array.h +303 -0
  144. data/ext/enclave/mruby/include/mruby/boxing_nan.h +169 -0
  145. data/ext/enclave/mruby/include/mruby/boxing_no.h +59 -0
  146. data/ext/enclave/mruby/include/mruby/boxing_word.h +248 -0
  147. data/ext/enclave/mruby/include/mruby/class.h +157 -0
  148. data/ext/enclave/mruby/include/mruby/common.h +127 -0
  149. data/ext/enclave/mruby/include/mruby/compile.h +187 -0
  150. data/ext/enclave/mruby/include/mruby/data.h +76 -0
  151. data/ext/enclave/mruby/include/mruby/debug.h +75 -0
  152. data/ext/enclave/mruby/include/mruby/dump.h +159 -0
  153. data/ext/enclave/mruby/include/mruby/endian.h +44 -0
  154. data/ext/enclave/mruby/include/mruby/error.h +168 -0
  155. data/ext/enclave/mruby/include/mruby/gc.h +77 -0
  156. data/ext/enclave/mruby/include/mruby/hash.h +234 -0
  157. data/ext/enclave/mruby/include/mruby/internal.h +278 -0
  158. data/ext/enclave/mruby/include/mruby/irep.h +142 -0
  159. data/ext/enclave/mruby/include/mruby/istruct.h +50 -0
  160. data/ext/enclave/mruby/include/mruby/khash.h +455 -0
  161. data/ext/enclave/mruby/include/mruby/mempool.h +19 -0
  162. data/ext/enclave/mruby/include/mruby/numeric.h +174 -0
  163. data/ext/enclave/mruby/include/mruby/object.h +44 -0
  164. data/ext/enclave/mruby/include/mruby/opcode.h +73 -0
  165. data/ext/enclave/mruby/include/mruby/ops.h +133 -0
  166. data/ext/enclave/mruby/include/mruby/presym/scanning.h +82 -0
  167. data/ext/enclave/mruby/include/mruby/presym.h +65 -0
  168. data/ext/enclave/mruby/include/mruby/proc.h +184 -0
  169. data/ext/enclave/mruby/include/mruby/range.h +77 -0
  170. data/ext/enclave/mruby/include/mruby/re.h +16 -0
  171. data/ext/enclave/mruby/include/mruby/string.h +428 -0
  172. data/ext/enclave/mruby/include/mruby/throw.h +81 -0
  173. data/ext/enclave/mruby/include/mruby/value.h +471 -0
  174. data/ext/enclave/mruby/include/mruby/variable.h +108 -0
  175. data/ext/enclave/mruby/include/mruby/version.h +143 -0
  176. data/ext/enclave/mruby/include/mruby.h +1632 -0
  177. data/ext/enclave/mruby/lib/mruby/amalgam.rb +568 -0
  178. data/ext/enclave/mruby/lib/mruby/build/command.rb +383 -0
  179. data/ext/enclave/mruby/lib/mruby/build/load_gems.rb +383 -0
  180. data/ext/enclave/mruby/lib/mruby/build.rb +616 -0
  181. data/ext/enclave/mruby/lib/mruby/core_ext.rb +61 -0
  182. data/ext/enclave/mruby/lib/mruby/doc.rb +51 -0
  183. data/ext/enclave/mruby/lib/mruby/gem.rb +585 -0
  184. data/ext/enclave/mruby/lib/mruby/lockfile.rb +81 -0
  185. data/ext/enclave/mruby/lib/mruby/presym.rb +167 -0
  186. data/ext/enclave/mruby/lib/mruby/source.rb +32 -0
  187. data/ext/enclave/mruby/mrbgems/default-no-fpu.gembox +3 -0
  188. data/ext/enclave/mruby/mrbgems/default-no-stdio.gembox +4 -0
  189. data/ext/enclave/mruby/mrbgems/default.gembox +25 -0
  190. data/ext/enclave/mruby/mrbgems/full-core.gembox +6 -0
  191. data/ext/enclave/mruby/mrbgems/hal-posix-dir/mrbgem.rake +7 -0
  192. data/ext/enclave/mruby/mrbgems/hal-posix-dir/src/dir_hal.c +193 -0
  193. data/ext/enclave/mruby/mrbgems/hal-posix-io/mrbgem.rake +8 -0
  194. data/ext/enclave/mruby/mrbgems/hal-posix-io/src/io_hal.c +602 -0
  195. data/ext/enclave/mruby/mrbgems/hal-posix-socket/mrbgem.rake +8 -0
  196. data/ext/enclave/mruby/mrbgems/hal-posix-socket/src/socket_hal.c +158 -0
  197. data/ext/enclave/mruby/mrbgems/hal-posix-task/README.md +102 -0
  198. data/ext/enclave/mruby/mrbgems/hal-posix-task/mrbgem.rake +8 -0
  199. data/ext/enclave/mruby/mrbgems/hal-posix-task/src/task_hal.c +252 -0
  200. data/ext/enclave/mruby/mrbgems/hal-win-dir/mrbgem.rake +7 -0
  201. data/ext/enclave/mruby/mrbgems/hal-win-dir/src/dir_hal.c +249 -0
  202. data/ext/enclave/mruby/mrbgems/hal-win-io/mrbgem.rake +11 -0
  203. data/ext/enclave/mruby/mrbgems/hal-win-io/src/io_hal.c +646 -0
  204. data/ext/enclave/mruby/mrbgems/hal-win-socket/mrbgem.rake +12 -0
  205. data/ext/enclave/mruby/mrbgems/hal-win-socket/src/socket_hal.c +177 -0
  206. data/ext/enclave/mruby/mrbgems/hal-win-task/README.md +109 -0
  207. data/ext/enclave/mruby/mrbgems/hal-win-task/mrbgem.rake +11 -0
  208. data/ext/enclave/mruby/mrbgems/hal-win-task/src/task_hal.c +187 -0
  209. data/ext/enclave/mruby/mrbgems/math.gembox +12 -0
  210. data/ext/enclave/mruby/mrbgems/metaprog.gembox +21 -0
  211. data/ext/enclave/mruby/mrbgems/mruby-array-ext/README.md +87 -0
  212. data/ext/enclave/mruby/mrbgems/mruby-array-ext/mrbgem.rake +5 -0
  213. data/ext/enclave/mruby/mrbgems/mruby-array-ext/mrblib/array.rb +784 -0
  214. data/ext/enclave/mruby/mrbgems/mruby-array-ext/src/array.c +1583 -0
  215. data/ext/enclave/mruby/mrbgems/mruby-array-ext/test/array.rb +849 -0
  216. data/ext/enclave/mruby/mrbgems/mruby-benchmark/README.md +257 -0
  217. data/ext/enclave/mruby/mrbgems/mruby-benchmark/mrbgem.rake +10 -0
  218. data/ext/enclave/mruby/mrbgems/mruby-benchmark/mrblib/benchmark.rb +131 -0
  219. data/ext/enclave/mruby/mrbgems/mruby-benchmark/test/benchmark.rb +244 -0
  220. data/ext/enclave/mruby/mrbgems/mruby-bigint/README-fgmp.md +154 -0
  221. data/ext/enclave/mruby/mrbgems/mruby-bigint/README.md +44 -0
  222. data/ext/enclave/mruby/mrbgems/mruby-bigint/core/bigint.c +6335 -0
  223. data/ext/enclave/mruby/mrbgems/mruby-bigint/core/bigint.h +117 -0
  224. data/ext/enclave/mruby/mrbgems/mruby-bigint/mrbgem.rake +10 -0
  225. data/ext/enclave/mruby/mrbgems/mruby-bigint/test/bigint.rb +157 -0
  226. data/ext/enclave/mruby/mrbgems/mruby-bin-config/README.md +46 -0
  227. data/ext/enclave/mruby/mrbgems/mruby-bin-config/mrbgem.rake +49 -0
  228. data/ext/enclave/mruby/mrbgems/mruby-bin-config/mruby-config +46 -0
  229. data/ext/enclave/mruby/mrbgems/mruby-bin-config/mruby-config.bat +92 -0
  230. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/README.md +63 -0
  231. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/bintest/mrdb.rb +283 -0
  232. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/bintest/print.rb +703 -0
  233. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/mrbgem.rake +10 -0
  234. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c +523 -0
  235. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.h +26 -0
  236. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c +238 -0
  237. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.h +14 -0
  238. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c +88 -0
  239. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.h +13 -0
  240. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apistring.c +34 -0
  241. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apistring.h +14 -0
  242. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c +436 -0
  243. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c +509 -0
  244. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdprint.c +71 -0
  245. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c +64 -0
  246. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c +768 -0
  247. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h +159 -0
  248. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdbconf.h +24 -0
  249. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdberror.h +19 -0
  250. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/README.md +94 -0
  251. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/bintest/mirb.rb +58 -0
  252. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/mrbgem.rake +7 -0
  253. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +808 -0
  254. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_buffer.c +1035 -0
  255. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_buffer.h +185 -0
  256. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_completion.c +797 -0
  257. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_completion.h +132 -0
  258. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_editor.c +1118 -0
  259. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_editor.h +153 -0
  260. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_highlight.c +516 -0
  261. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_highlight.h +95 -0
  262. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_history.c +185 -0
  263. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_history.h +76 -0
  264. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_term.c +491 -0
  265. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_term.h +137 -0
  266. data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/README.md +58 -0
  267. data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/bintest/mrbc.rb +30 -0
  268. data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/mrbgem.rake +15 -0
  269. data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c +362 -0
  270. data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/stub.c +104 -0
  271. data/ext/enclave/mruby/mrbgems/mruby-bin-mruby/README.md +47 -0
  272. data/ext/enclave/mruby/mrbgems/mruby-bin-mruby/bintest/mruby.rb +178 -0
  273. data/ext/enclave/mruby/mrbgems/mruby-bin-mruby/mrbgem.rake +7 -0
  274. data/ext/enclave/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +380 -0
  275. data/ext/enclave/mruby/mrbgems/mruby-bin-strip/README.md +38 -0
  276. data/ext/enclave/mruby/mrbgems/mruby-bin-strip/bintest/mruby_strip.rb +73 -0
  277. data/ext/enclave/mruby/mrbgems/mruby-bin-strip/mrbgem.rake +7 -0
  278. data/ext/enclave/mruby/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby_strip.c +139 -0
  279. data/ext/enclave/mruby/mrbgems/mruby-binding/README.md +256 -0
  280. data/ext/enclave/mruby/mrbgems/mruby-binding/mrbgem.rake +7 -0
  281. data/ext/enclave/mruby/mrbgems/mruby-binding/src/binding.c +518 -0
  282. data/ext/enclave/mruby/mrbgems/mruby-binding/test/binding.c +14 -0
  283. data/ext/enclave/mruby/mrbgems/mruby-binding/test/binding.rb +64 -0
  284. data/ext/enclave/mruby/mrbgems/mruby-catch/README.md +94 -0
  285. data/ext/enclave/mruby/mrbgems/mruby-catch/mrbgem.rake +5 -0
  286. data/ext/enclave/mruby/mrbgems/mruby-catch/mrblib/catch.rb +29 -0
  287. data/ext/enclave/mruby/mrbgems/mruby-catch/src/catch.c +149 -0
  288. data/ext/enclave/mruby/mrbgems/mruby-catch/test/catch.rb +86 -0
  289. data/ext/enclave/mruby/mrbgems/mruby-class-ext/README.md +81 -0
  290. data/ext/enclave/mruby/mrbgems/mruby-class-ext/mrbgem.rake +5 -0
  291. data/ext/enclave/mruby/mrbgems/mruby-class-ext/src/class.c +377 -0
  292. data/ext/enclave/mruby/mrbgems/mruby-class-ext/test/class.rb +46 -0
  293. data/ext/enclave/mruby/mrbgems/mruby-class-ext/test/module.rb +109 -0
  294. data/ext/enclave/mruby/mrbgems/mruby-cmath/README.md +45 -0
  295. data/ext/enclave/mruby/mrbgems/mruby-cmath/mrbgem.rake +8 -0
  296. data/ext/enclave/mruby/mrbgems/mruby-cmath/src/cmath.c +426 -0
  297. data/ext/enclave/mruby/mrbgems/mruby-cmath/test/cmath.rb +41 -0
  298. data/ext/enclave/mruby/mrbgems/mruby-compar-ext/README.md +65 -0
  299. data/ext/enclave/mruby/mrbgems/mruby-compar-ext/mrbgem.rake +5 -0
  300. data/ext/enclave/mruby/mrbgems/mruby-compar-ext/mrblib/compar.rb +75 -0
  301. data/ext/enclave/mruby/mrbgems/mruby-compar-ext/test/compar.rb +21 -0
  302. data/ext/enclave/mruby/mrbgems/mruby-compiler/README.md +28 -0
  303. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/codegen.c +7316 -0
  304. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/keywords +52 -0
  305. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/lex.def +207 -0
  306. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/node.h +784 -0
  307. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/parse.y +8977 -0
  308. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/y.tab.c +16136 -0
  309. data/ext/enclave/mruby/mrbgems/mruby-compiler/mrbgem.rake +42 -0
  310. data/ext/enclave/mruby/mrbgems/mruby-complex/README.md +55 -0
  311. data/ext/enclave/mruby/mrbgems/mruby-complex/mrbgem.rake +7 -0
  312. data/ext/enclave/mruby/mrbgems/mruby-complex/mrblib/complex.rb +259 -0
  313. data/ext/enclave/mruby/mrbgems/mruby-complex/src/complex.c +597 -0
  314. data/ext/enclave/mruby/mrbgems/mruby-complex/test/complex.rb +174 -0
  315. data/ext/enclave/mruby/mrbgems/mruby-data/README.md +126 -0
  316. data/ext/enclave/mruby/mrbgems/mruby-data/mrbgem.rake +5 -0
  317. data/ext/enclave/mruby/mrbgems/mruby-data/src/data.c +550 -0
  318. data/ext/enclave/mruby/mrbgems/mruby-data/test/data.rb +76 -0
  319. data/ext/enclave/mruby/mrbgems/mruby-dir/README.md +53 -0
  320. data/ext/enclave/mruby/mrbgems/mruby-dir/include/dir_hal.h +79 -0
  321. data/ext/enclave/mruby/mrbgems/mruby-dir/mrbgem.rake +35 -0
  322. data/ext/enclave/mruby/mrbgems/mruby-dir/mrblib/dir.rb +124 -0
  323. data/ext/enclave/mruby/mrbgems/mruby-dir/src/dir.c +493 -0
  324. data/ext/enclave/mruby/mrbgems/mruby-dir/test/dir.rb +138 -0
  325. data/ext/enclave/mruby/mrbgems/mruby-dir/test/dirtest.c +125 -0
  326. data/ext/enclave/mruby/mrbgems/mruby-encoding/README.md +96 -0
  327. data/ext/enclave/mruby/mrbgems/mruby-encoding/mrbgem.rake +8 -0
  328. data/ext/enclave/mruby/mrbgems/mruby-encoding/src/encoding.c +128 -0
  329. data/ext/enclave/mruby/mrbgems/mruby-encoding/test/numeric.rb +27 -0
  330. data/ext/enclave/mruby/mrbgems/mruby-encoding/test/string.rb +30 -0
  331. data/ext/enclave/mruby/mrbgems/mruby-enum-chain/README.md +80 -0
  332. data/ext/enclave/mruby/mrbgems/mruby-enum-chain/mrbgem.rake +6 -0
  333. data/ext/enclave/mruby/mrbgems/mruby-enum-chain/mrblib/chain.rb +149 -0
  334. data/ext/enclave/mruby/mrbgems/mruby-enum-chain/test/enum_chain.rb +108 -0
  335. data/ext/enclave/mruby/mrbgems/mruby-enum-ext/README.md +487 -0
  336. data/ext/enclave/mruby/mrbgems/mruby-enum-ext/mrbgem.rake +5 -0
  337. data/ext/enclave/mruby/mrbgems/mruby-enum-ext/mrblib/enum.rb +938 -0
  338. data/ext/enclave/mruby/mrbgems/mruby-enum-ext/test/enum.rb +223 -0
  339. data/ext/enclave/mruby/mrbgems/mruby-enum-lazy/README.md +91 -0
  340. data/ext/enclave/mruby/mrbgems/mruby-enum-lazy/mrbgem.rake +7 -0
  341. data/ext/enclave/mruby/mrbgems/mruby-enum-lazy/mrblib/lazy.rb +363 -0
  342. data/ext/enclave/mruby/mrbgems/mruby-enum-lazy/test/lazy.rb +59 -0
  343. data/ext/enclave/mruby/mrbgems/mruby-enumerator/README.md +89 -0
  344. data/ext/enclave/mruby/mrbgems/mruby-enumerator/mrbgem.rake +6 -0
  345. data/ext/enclave/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb +861 -0
  346. data/ext/enclave/mruby/mrbgems/mruby-enumerator/test/enumerator.rb +664 -0
  347. data/ext/enclave/mruby/mrbgems/mruby-errno/README.md +83 -0
  348. data/ext/enclave/mruby/mrbgems/mruby-errno/mrbgem.rake +5 -0
  349. data/ext/enclave/mruby/mrbgems/mruby-errno/mrblib/errno.rb +50 -0
  350. data/ext/enclave/mruby/mrbgems/mruby-errno/src/errno.c +335 -0
  351. data/ext/enclave/mruby/mrbgems/mruby-errno/src/gen.rb +18 -0
  352. data/ext/enclave/mruby/mrbgems/mruby-errno/src/known_errors.def +156 -0
  353. data/ext/enclave/mruby/mrbgems/mruby-errno/src/known_errors_def.cstub +780 -0
  354. data/ext/enclave/mruby/mrbgems/mruby-errno/test/errno.rb +57 -0
  355. data/ext/enclave/mruby/mrbgems/mruby-error/README.md +103 -0
  356. data/ext/enclave/mruby/mrbgems/mruby-error/mrbgem.rake +5 -0
  357. data/ext/enclave/mruby/mrbgems/mruby-error/src/exception.c +143 -0
  358. data/ext/enclave/mruby/mrbgems/mruby-error/test/exception.c +60 -0
  359. data/ext/enclave/mruby/mrbgems/mruby-error/test/exception.rb +55 -0
  360. data/ext/enclave/mruby/mrbgems/mruby-eval/README.md +26 -0
  361. data/ext/enclave/mruby/mrbgems/mruby-eval/mrbgem.rake +10 -0
  362. data/ext/enclave/mruby/mrbgems/mruby-eval/src/eval.c +437 -0
  363. data/ext/enclave/mruby/mrbgems/mruby-eval/test/binding.rb +81 -0
  364. data/ext/enclave/mruby/mrbgems/mruby-eval/test/eval.rb +185 -0
  365. data/ext/enclave/mruby/mrbgems/mruby-exit/mrbgem.rake +5 -0
  366. data/ext/enclave/mruby/mrbgems/mruby-exit/src/mruby_exit.c +83 -0
  367. data/ext/enclave/mruby/mrbgems/mruby-fiber/mrbgem.rake +5 -0
  368. data/ext/enclave/mruby/mrbgems/mruby-fiber/src/fiber.c +575 -0
  369. data/ext/enclave/mruby/mrbgems/mruby-fiber/test/fiber.rb +210 -0
  370. data/ext/enclave/mruby/mrbgems/mruby-fiber/test/fiber2.rb +155 -0
  371. data/ext/enclave/mruby/mrbgems/mruby-fiber/test/fibertest.c +87 -0
  372. data/ext/enclave/mruby/mrbgems/mruby-hash-ext/README.md +392 -0
  373. data/ext/enclave/mruby/mrbgems/mruby-hash-ext/mrbgem.rake +6 -0
  374. data/ext/enclave/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb +408 -0
  375. data/ext/enclave/mruby/mrbgems/mruby-hash-ext/src/hash_ext.c +392 -0
  376. data/ext/enclave/mruby/mrbgems/mruby-hash-ext/test/hash.rb +317 -0
  377. data/ext/enclave/mruby/mrbgems/mruby-io/README.md +198 -0
  378. data/ext/enclave/mruby/mrbgems/mruby-io/include/io_hal.h +451 -0
  379. data/ext/enclave/mruby/mrbgems/mruby-io/include/mruby/io.h +76 -0
  380. data/ext/enclave/mruby/mrbgems/mruby-io/mrbgem.rake +34 -0
  381. data/ext/enclave/mruby/mrbgems/mruby-io/mrblib/file.rb +109 -0
  382. data/ext/enclave/mruby/mrbgems/mruby-io/mrblib/file_constants.rb +24 -0
  383. data/ext/enclave/mruby/mrbgems/mruby-io/mrblib/io.rb +303 -0
  384. data/ext/enclave/mruby/mrbgems/mruby-io/mrblib/kernel.rb +175 -0
  385. data/ext/enclave/mruby/mrbgems/mruby-io/src/file.c +1192 -0
  386. data/ext/enclave/mruby/mrbgems/mruby-io/src/file_test.c +403 -0
  387. data/ext/enclave/mruby/mrbgems/mruby-io/src/io.c +2260 -0
  388. data/ext/enclave/mruby/mrbgems/mruby-io/src/mruby_io_gem.c +21 -0
  389. data/ext/enclave/mruby/mrbgems/mruby-io/test/file.rb +415 -0
  390. data/ext/enclave/mruby/mrbgems/mruby-io/test/file_test.rb +112 -0
  391. data/ext/enclave/mruby/mrbgems/mruby-io/test/io.rb +668 -0
  392. data/ext/enclave/mruby/mrbgems/mruby-io/test/mruby_io_test.c +293 -0
  393. data/ext/enclave/mruby/mrbgems/mruby-kernel-ext/README.md +165 -0
  394. data/ext/enclave/mruby/mrbgems/mruby-kernel-ext/mrbgem.rake +5 -0
  395. data/ext/enclave/mruby/mrbgems/mruby-kernel-ext/src/kernel.c +316 -0
  396. data/ext/enclave/mruby/mrbgems/mruby-kernel-ext/test/kernel.rb +134 -0
  397. data/ext/enclave/mruby/mrbgems/mruby-math/README.md +77 -0
  398. data/ext/enclave/mruby/mrbgems/mruby-math/mrbgem.rake +5 -0
  399. data/ext/enclave/mruby/mrbgems/mruby-math/src/math.c +753 -0
  400. data/ext/enclave/mruby/mrbgems/mruby-math/test/math.rb +201 -0
  401. data/ext/enclave/mruby/mrbgems/mruby-metaprog/README.md +123 -0
  402. data/ext/enclave/mruby/mrbgems/mruby-metaprog/mrbgem.rake +5 -0
  403. data/ext/enclave/mruby/mrbgems/mruby-metaprog/src/metaprog.c +739 -0
  404. data/ext/enclave/mruby/mrbgems/mruby-metaprog/test/metaprog.rb +465 -0
  405. data/ext/enclave/mruby/mrbgems/mruby-method/README.md +66 -0
  406. data/ext/enclave/mruby/mrbgems/mruby-method/mrbgem.rake +7 -0
  407. data/ext/enclave/mruby/mrbgems/mruby-method/mrblib/method.rb +73 -0
  408. data/ext/enclave/mruby/mrbgems/mruby-method/src/method.c +890 -0
  409. data/ext/enclave/mruby/mrbgems/mruby-method/test/method.rb +514 -0
  410. data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/README.md +78 -0
  411. data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/mrbgem.rake +5 -0
  412. data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb +125 -0
  413. data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c +527 -0
  414. data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/test/numeric.rb +137 -0
  415. data/ext/enclave/mruby/mrbgems/mruby-object-ext/README.md +144 -0
  416. data/ext/enclave/mruby/mrbgems/mruby-object-ext/mrbgem.rake +5 -0
  417. data/ext/enclave/mruby/mrbgems/mruby-object-ext/mrblib/object.rb +33 -0
  418. data/ext/enclave/mruby/mrbgems/mruby-object-ext/src/object.c +128 -0
  419. data/ext/enclave/mruby/mrbgems/mruby-object-ext/test/nil.rb +16 -0
  420. data/ext/enclave/mruby/mrbgems/mruby-object-ext/test/object.rb +67 -0
  421. data/ext/enclave/mruby/mrbgems/mruby-object-ext/test/object_ext.c +17 -0
  422. data/ext/enclave/mruby/mrbgems/mruby-objectspace/README.md +59 -0
  423. data/ext/enclave/mruby/mrbgems/mruby-objectspace/mrbgem.rake +5 -0
  424. data/ext/enclave/mruby/mrbgems/mruby-objectspace/src/mruby_objectspace.c +188 -0
  425. data/ext/enclave/mruby/mrbgems/mruby-objectspace/test/objectspace.rb +60 -0
  426. data/ext/enclave/mruby/mrbgems/mruby-os-memsize/README.md +75 -0
  427. data/ext/enclave/mruby/mrbgems/mruby-os-memsize/mrbgem.rake +10 -0
  428. data/ext/enclave/mruby/mrbgems/mruby-os-memsize/src/memsize.c +271 -0
  429. data/ext/enclave/mruby/mrbgems/mruby-os-memsize/test/memsize.rb +63 -0
  430. data/ext/enclave/mruby/mrbgems/mruby-pack/README.md +140 -0
  431. data/ext/enclave/mruby/mrbgems/mruby-pack/mrbgem.rake +5 -0
  432. data/ext/enclave/mruby/mrbgems/mruby-pack/src/pack.c +2129 -0
  433. data/ext/enclave/mruby/mrbgems/mruby-pack/test/pack.rb +202 -0
  434. data/ext/enclave/mruby/mrbgems/mruby-proc-binding/README.md +140 -0
  435. data/ext/enclave/mruby/mrbgems/mruby-proc-binding/mrbgem.rake +10 -0
  436. data/ext/enclave/mruby/mrbgems/mruby-proc-binding/src/proc_binding.c +76 -0
  437. data/ext/enclave/mruby/mrbgems/mruby-proc-binding/test/proc_binding.c +14 -0
  438. data/ext/enclave/mruby/mrbgems/mruby-proc-binding/test/proc_binding.rb +22 -0
  439. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/README.md +107 -0
  440. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/mrbgem.rake +5 -0
  441. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/mrblib/proc.rb +130 -0
  442. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/src/proc.c +267 -0
  443. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/test/proc.c +62 -0
  444. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/test/proc.rb +130 -0
  445. data/ext/enclave/mruby/mrbgems/mruby-random/README.md +272 -0
  446. data/ext/enclave/mruby/mrbgems/mruby-random/mrbgem.rake +5 -0
  447. data/ext/enclave/mruby/mrbgems/mruby-random/src/random.c +608 -0
  448. data/ext/enclave/mruby/mrbgems/mruby-random/test/random.rb +151 -0
  449. data/ext/enclave/mruby/mrbgems/mruby-range-ext/README.md +93 -0
  450. data/ext/enclave/mruby/mrbgems/mruby-range-ext/mrbgem.rake +5 -0
  451. data/ext/enclave/mruby/mrbgems/mruby-range-ext/mrblib/range.rb +155 -0
  452. data/ext/enclave/mruby/mrbgems/mruby-range-ext/src/range.c +236 -0
  453. data/ext/enclave/mruby/mrbgems/mruby-range-ext/test/range.rb +211 -0
  454. data/ext/enclave/mruby/mrbgems/mruby-rational/README.md +61 -0
  455. data/ext/enclave/mruby/mrbgems/mruby-rational/mrbgem.rake +7 -0
  456. data/ext/enclave/mruby/mrbgems/mruby-rational/mrblib/rational.rb +66 -0
  457. data/ext/enclave/mruby/mrbgems/mruby-rational/src/rational.c +1269 -0
  458. data/ext/enclave/mruby/mrbgems/mruby-rational/test/rational.rb +316 -0
  459. data/ext/enclave/mruby/mrbgems/mruby-set/LICENSE +24 -0
  460. data/ext/enclave/mruby/mrbgems/mruby-set/README.md +260 -0
  461. data/ext/enclave/mruby/mrbgems/mruby-set/mrbgem.rake +9 -0
  462. data/ext/enclave/mruby/mrbgems/mruby-set/mrblib/set.rb +325 -0
  463. data/ext/enclave/mruby/mrbgems/mruby-set/mruby-set.gem +6 -0
  464. data/ext/enclave/mruby/mrbgems/mruby-set/src/set.c +1535 -0
  465. data/ext/enclave/mruby/mrbgems/mruby-set/test/set.rb +764 -0
  466. data/ext/enclave/mruby/mrbgems/mruby-sleep/README.md +29 -0
  467. data/ext/enclave/mruby/mrbgems/mruby-sleep/example/sleep.rb +2 -0
  468. data/ext/enclave/mruby/mrbgems/mruby-sleep/mrbgem.rake +5 -0
  469. data/ext/enclave/mruby/mrbgems/mruby-sleep/src/sleep.c +187 -0
  470. data/ext/enclave/mruby/mrbgems/mruby-sleep/test/sleep_test.rb +29 -0
  471. data/ext/enclave/mruby/mrbgems/mruby-socket/README.md +56 -0
  472. data/ext/enclave/mruby/mrbgems/mruby-socket/include/socket_hal.h +83 -0
  473. data/ext/enclave/mruby/mrbgems/mruby-socket/mrbgem.rake +37 -0
  474. data/ext/enclave/mruby/mrbgems/mruby-socket/mrblib/socket.rb +1131 -0
  475. data/ext/enclave/mruby/mrbgems/mruby-socket/src/const.cstub +480 -0
  476. data/ext/enclave/mruby/mrbgems/mruby-socket/src/const.def +172 -0
  477. data/ext/enclave/mruby/mrbgems/mruby-socket/src/gen.rb +17 -0
  478. data/ext/enclave/mruby/mrbgems/mruby-socket/src/socket.c +1374 -0
  479. data/ext/enclave/mruby/mrbgems/mruby-socket/test/addrinfo.rb +91 -0
  480. data/ext/enclave/mruby/mrbgems/mruby-socket/test/basicsocket.rb +17 -0
  481. data/ext/enclave/mruby/mrbgems/mruby-socket/test/ipsocket.rb +44 -0
  482. data/ext/enclave/mruby/mrbgems/mruby-socket/test/socket.rb +38 -0
  483. data/ext/enclave/mruby/mrbgems/mruby-socket/test/sockettest.c +84 -0
  484. data/ext/enclave/mruby/mrbgems/mruby-socket/test/tcpsocket.rb +4 -0
  485. data/ext/enclave/mruby/mrbgems/mruby-socket/test/udpsocket.rb +16 -0
  486. data/ext/enclave/mruby/mrbgems/mruby-socket/test/unix.rb +130 -0
  487. data/ext/enclave/mruby/mrbgems/mruby-sprintf/README.md +235 -0
  488. data/ext/enclave/mruby/mrbgems/mruby-sprintf/mrbgem.rake +5 -0
  489. data/ext/enclave/mruby/mrbgems/mruby-sprintf/mrblib/string.rb +24 -0
  490. data/ext/enclave/mruby/mrbgems/mruby-sprintf/src/sprintf.c +1195 -0
  491. data/ext/enclave/mruby/mrbgems/mruby-sprintf/test/sprintf.rb +92 -0
  492. data/ext/enclave/mruby/mrbgems/mruby-strftime/README.md +140 -0
  493. data/ext/enclave/mruby/mrbgems/mruby-strftime/mrbgem.rake +7 -0
  494. data/ext/enclave/mruby/mrbgems/mruby-strftime/src/strftime.c +119 -0
  495. data/ext/enclave/mruby/mrbgems/mruby-strftime/test/strftime.rb +152 -0
  496. data/ext/enclave/mruby/mrbgems/mruby-string-ext/README.md +886 -0
  497. data/ext/enclave/mruby/mrbgems/mruby-string-ext/mrbgem.rake +5 -0
  498. data/ext/enclave/mruby/mrbgems/mruby-string-ext/mrblib/string.rb +166 -0
  499. data/ext/enclave/mruby/mrbgems/mruby-string-ext/src/string.c +2290 -0
  500. data/ext/enclave/mruby/mrbgems/mruby-string-ext/test/numeric.rb +27 -0
  501. data/ext/enclave/mruby/mrbgems/mruby-string-ext/test/range.rb +26 -0
  502. data/ext/enclave/mruby/mrbgems/mruby-string-ext/test/string.rb +765 -0
  503. data/ext/enclave/mruby/mrbgems/mruby-struct/README.md +105 -0
  504. data/ext/enclave/mruby/mrbgems/mruby-struct/mrbgem.rake +5 -0
  505. data/ext/enclave/mruby/mrbgems/mruby-struct/mrblib/struct.rb +69 -0
  506. data/ext/enclave/mruby/mrbgems/mruby-struct/src/struct.c +812 -0
  507. data/ext/enclave/mruby/mrbgems/mruby-struct/test/struct.rb +303 -0
  508. data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/README.md +50 -0
  509. data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/mrbgem.rake +5 -0
  510. data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/mrblib/symbol.rb +72 -0
  511. data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/src/symbol.c +79 -0
  512. data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/test/symbol.rb +55 -0
  513. data/ext/enclave/mruby/mrbgems/mruby-task/README.md +770 -0
  514. data/ext/enclave/mruby/mrbgems/mruby-task/examples/inspection.rb +65 -0
  515. data/ext/enclave/mruby/mrbgems/mruby-task/examples/priority.rb +41 -0
  516. data/ext/enclave/mruby/mrbgems/mruby-task/examples/producer_consumer.rb +58 -0
  517. data/ext/enclave/mruby/mrbgems/mruby-task/examples/simple.rb +27 -0
  518. data/ext/enclave/mruby/mrbgems/mruby-task/examples/statistics.rb +59 -0
  519. data/ext/enclave/mruby/mrbgems/mruby-task/examples/suspend_resume.rb +47 -0
  520. data/ext/enclave/mruby/mrbgems/mruby-task/examples/task_pass.rb +21 -0
  521. data/ext/enclave/mruby/mrbgems/mruby-task/include/task.h +143 -0
  522. data/ext/enclave/mruby/mrbgems/mruby-task/include/task_hal.h +162 -0
  523. data/ext/enclave/mruby/mrbgems/mruby-task/mrbgem.rake +36 -0
  524. data/ext/enclave/mruby/mrbgems/mruby-task/src/task.c +1573 -0
  525. data/ext/enclave/mruby/mrbgems/mruby-task/test/task.rb +185 -0
  526. data/ext/enclave/mruby/mrbgems/mruby-test/README.md +7 -0
  527. data/ext/enclave/mruby/mrbgems/mruby-test/driver.c +315 -0
  528. data/ext/enclave/mruby/mrbgems/mruby-test/mrbgem.rake +173 -0
  529. data/ext/enclave/mruby/mrbgems/mruby-test/vformat.c +151 -0
  530. data/ext/enclave/mruby/mrbgems/mruby-test-inline-struct/mrbgem.rake +5 -0
  531. data/ext/enclave/mruby/mrbgems/mruby-test-inline-struct/test/inline.c +92 -0
  532. data/ext/enclave/mruby/mrbgems/mruby-test-inline-struct/test/inline.rb +118 -0
  533. data/ext/enclave/mruby/mrbgems/mruby-time/README.md +102 -0
  534. data/ext/enclave/mruby/mrbgems/mruby-time/include/mruby/time.h +27 -0
  535. data/ext/enclave/mruby/mrbgems/mruby-time/mrbgem.rake +5 -0
  536. data/ext/enclave/mruby/mrbgems/mruby-time/src/time.c +1739 -0
  537. data/ext/enclave/mruby/mrbgems/mruby-time/test/time.rb +313 -0
  538. data/ext/enclave/mruby/mrbgems/mruby-toplevel-ext/README.md +32 -0
  539. data/ext/enclave/mruby/mrbgems/mruby-toplevel-ext/mrbgem.rake +5 -0
  540. data/ext/enclave/mruby/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb +24 -0
  541. data/ext/enclave/mruby/mrbgems/mruby-toplevel-ext/test/toplevel.rb +23 -0
  542. data/ext/enclave/mruby/mrbgems/stdlib-ext.gembox +21 -0
  543. data/ext/enclave/mruby/mrbgems/stdlib-io.gembox +15 -0
  544. data/ext/enclave/mruby/mrbgems/stdlib.gembox +63 -0
  545. data/ext/enclave/mruby/mrblib/10error.rb +23 -0
  546. data/ext/enclave/mruby/mrblib/array.rb +102 -0
  547. data/ext/enclave/mruby/mrblib/compar.rb +102 -0
  548. data/ext/enclave/mruby/mrblib/enum.rb +358 -0
  549. data/ext/enclave/mruby/mrblib/hash.rb +276 -0
  550. data/ext/enclave/mruby/mrblib/kernel.rb +45 -0
  551. data/ext/enclave/mruby/mrblib/numeric.rb +160 -0
  552. data/ext/enclave/mruby/mrblib/range.rb +98 -0
  553. data/ext/enclave/mruby/mrblib/string.rb +173 -0
  554. data/ext/enclave/mruby/mrblib/symbol.rb +8 -0
  555. data/ext/enclave/mruby/oss-fuzz/mruby_fuzzer.c +18 -0
  556. data/ext/enclave/mruby/oss-fuzz/proto_to_ruby.h +55 -0
  557. data/ext/enclave/mruby/src/allocf.c +37 -0
  558. data/ext/enclave/mruby/src/array.c +2302 -0
  559. data/ext/enclave/mruby/src/backtrace.c +294 -0
  560. data/ext/enclave/mruby/src/cdump.c +498 -0
  561. data/ext/enclave/mruby/src/class.c +4394 -0
  562. data/ext/enclave/mruby/src/codedump.c +693 -0
  563. data/ext/enclave/mruby/src/debug.c +290 -0
  564. data/ext/enclave/mruby/src/dump.c +998 -0
  565. data/ext/enclave/mruby/src/enum.c +30 -0
  566. data/ext/enclave/mruby/src/error.c +937 -0
  567. data/ext/enclave/mruby/src/etc.c +421 -0
  568. data/ext/enclave/mruby/src/fmt_fp.c +372 -0
  569. data/ext/enclave/mruby/src/gc.c +1610 -0
  570. data/ext/enclave/mruby/src/hash.c +2355 -0
  571. data/ext/enclave/mruby/src/init.c +50 -0
  572. data/ext/enclave/mruby/src/kernel.c +718 -0
  573. data/ext/enclave/mruby/src/load.c +760 -0
  574. data/ext/enclave/mruby/src/mempool.c +225 -0
  575. data/ext/enclave/mruby/src/numeric.c +2420 -0
  576. data/ext/enclave/mruby/src/numops.c +112 -0
  577. data/ext/enclave/mruby/src/object.c +883 -0
  578. data/ext/enclave/mruby/src/print.c +136 -0
  579. data/ext/enclave/mruby/src/proc.c +572 -0
  580. data/ext/enclave/mruby/src/range.c +597 -0
  581. data/ext/enclave/mruby/src/readfloat.c +228 -0
  582. data/ext/enclave/mruby/src/readint.c +27 -0
  583. data/ext/enclave/mruby/src/readnum.c +43 -0
  584. data/ext/enclave/mruby/src/state.c +247 -0
  585. data/ext/enclave/mruby/src/string.c +3577 -0
  586. data/ext/enclave/mruby/src/symbol.c +1023 -0
  587. data/ext/enclave/mruby/src/value_array.h +28 -0
  588. data/ext/enclave/mruby/src/variable.c +1475 -0
  589. data/ext/enclave/mruby/src/version.c +17 -0
  590. data/ext/enclave/mruby/src/vm.c +3696 -0
  591. data/ext/enclave/mruby/tasks/amalgam.rake +34 -0
  592. data/ext/enclave/mruby/tasks/benchmark.rake +93 -0
  593. data/ext/enclave/mruby/tasks/bin.rake +23 -0
  594. data/ext/enclave/mruby/tasks/core.rake +12 -0
  595. data/ext/enclave/mruby/tasks/doc.rake +118 -0
  596. data/ext/enclave/mruby/tasks/install.rake +40 -0
  597. data/ext/enclave/mruby/tasks/libmruby.rake +90 -0
  598. data/ext/enclave/mruby/tasks/mrbgems.rake +152 -0
  599. data/ext/enclave/mruby/tasks/mrblib.rake +29 -0
  600. data/ext/enclave/mruby/tasks/presym.rake +57 -0
  601. data/ext/enclave/mruby/tasks/test.rake +84 -0
  602. data/ext/enclave/mruby/tasks/toolchains/android.rake +228 -0
  603. data/ext/enclave/mruby/tasks/toolchains/clang.rake +8 -0
  604. data/ext/enclave/mruby/tasks/toolchains/emscripten.rake +57 -0
  605. data/ext/enclave/mruby/tasks/toolchains/gcc.rake +74 -0
  606. data/ext/enclave/mruby/tasks/toolchains/openwrt.rake +32 -0
  607. data/ext/enclave/mruby/tasks/toolchains/visualcpp.rake +48 -0
  608. data/ext/enclave/mruby/test/assert.rb +404 -0
  609. data/ext/enclave/mruby/test/bintest.rb +55 -0
  610. data/ext/enclave/mruby/test/t/argumenterror.rb +37 -0
  611. data/ext/enclave/mruby/test/t/array.rb +478 -0
  612. data/ext/enclave/mruby/test/t/basicobject.rb +10 -0
  613. data/ext/enclave/mruby/test/t/bs_block.rb +621 -0
  614. data/ext/enclave/mruby/test/t/bs_literal.rb +38 -0
  615. data/ext/enclave/mruby/test/t/class.rb +505 -0
  616. data/ext/enclave/mruby/test/t/codegen.rb +196 -0
  617. data/ext/enclave/mruby/test/t/comparable.rb +79 -0
  618. data/ext/enclave/mruby/test/t/ensure.rb +36 -0
  619. data/ext/enclave/mruby/test/t/enumerable.rb +134 -0
  620. data/ext/enclave/mruby/test/t/exception.rb +425 -0
  621. data/ext/enclave/mruby/test/t/false.rb +31 -0
  622. data/ext/enclave/mruby/test/t/float.rb +296 -0
  623. data/ext/enclave/mruby/test/t/gc.rb +45 -0
  624. data/ext/enclave/mruby/test/t/hash.rb +976 -0
  625. data/ext/enclave/mruby/test/t/indexerror.rb +6 -0
  626. data/ext/enclave/mruby/test/t/integer.rb +247 -0
  627. data/ext/enclave/mruby/test/t/iterations.rb +61 -0
  628. data/ext/enclave/mruby/test/t/kernel.rb +462 -0
  629. data/ext/enclave/mruby/test/t/lang.rb +74 -0
  630. data/ext/enclave/mruby/test/t/literals.rb +386 -0
  631. data/ext/enclave/mruby/test/t/localjumperror.rb +13 -0
  632. data/ext/enclave/mruby/test/t/methods.rb +138 -0
  633. data/ext/enclave/mruby/test/t/module.rb +931 -0
  634. data/ext/enclave/mruby/test/t/nameerror.rb +28 -0
  635. data/ext/enclave/mruby/test/t/nil.rb +39 -0
  636. data/ext/enclave/mruby/test/t/nomethoderror.rb +22 -0
  637. data/ext/enclave/mruby/test/t/numeric.rb +114 -0
  638. data/ext/enclave/mruby/test/t/object.rb +10 -0
  639. data/ext/enclave/mruby/test/t/proc.rb +198 -0
  640. data/ext/enclave/mruby/test/t/range.rb +194 -0
  641. data/ext/enclave/mruby/test/t/rangeerror.rb +6 -0
  642. data/ext/enclave/mruby/test/t/regexperror.rb +4 -0
  643. data/ext/enclave/mruby/test/t/runtimeerror.rb +6 -0
  644. data/ext/enclave/mruby/test/t/standarderror.rb +6 -0
  645. data/ext/enclave/mruby/test/t/string.rb +981 -0
  646. data/ext/enclave/mruby/test/t/superclass.rb +46 -0
  647. data/ext/enclave/mruby/test/t/symbol.rb +30 -0
  648. data/ext/enclave/mruby/test/t/syntax.rb +1296 -0
  649. data/ext/enclave/mruby/test/t/true.rb +31 -0
  650. data/ext/enclave/mruby/test/t/typeerror.rb +6 -0
  651. data/ext/enclave/mruby/test/t/unicode.rb +39 -0
  652. data/ext/enclave/mruby/test/t/vformat.rb +57 -0
  653. data/ext/enclave/mruby/tools/lrama/LEGAL.md +12 -0
  654. data/ext/enclave/mruby/tools/lrama/MIT +21 -0
  655. data/ext/enclave/mruby/tools/lrama/NEWS.md +696 -0
  656. data/ext/enclave/mruby/tools/lrama/exe/lrama +7 -0
  657. data/ext/enclave/mruby/tools/lrama/lib/lrama/bitmap.rb +34 -0
  658. data/ext/enclave/mruby/tools/lrama/lib/lrama/command.rb +68 -0
  659. data/ext/enclave/mruby/tools/lrama/lib/lrama/context.rb +499 -0
  660. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/derivation.rb +66 -0
  661. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/example.rb +129 -0
  662. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/path.rb +29 -0
  663. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/production_path.rb +19 -0
  664. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/start_path.rb +23 -0
  665. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/state_item.rb +8 -0
  666. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/transition_path.rb +19 -0
  667. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/triple.rb +23 -0
  668. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples.rb +298 -0
  669. data/ext/enclave/mruby/tools/lrama/lib/lrama/diagnostics.rb +36 -0
  670. data/ext/enclave/mruby/tools/lrama/lib/lrama/digraph.rb +83 -0
  671. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/auxiliary.rb +9 -0
  672. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/binding.rb +67 -0
  673. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/destructor_code.rb +42 -0
  674. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/initial_action_code.rb +36 -0
  675. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/no_reference_code.rb +30 -0
  676. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/printer_code.rb +42 -0
  677. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/rule_action.rb +92 -0
  678. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code.rb +53 -0
  679. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/counter.rb +17 -0
  680. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/destructor.rb +11 -0
  681. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/error_token.rb +11 -0
  682. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/parameterizing_rule/resolver.rb +62 -0
  683. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/parameterizing_rule/rhs.rb +40 -0
  684. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/parameterizing_rule/rule.rb +24 -0
  685. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/parameterizing_rule.rb +5 -0
  686. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/percent_code.rb +14 -0
  687. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/precedence.rb +13 -0
  688. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/printer.rb +11 -0
  689. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/reference.rb +16 -0
  690. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/rule.rb +75 -0
  691. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/rule_builder.rb +255 -0
  692. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/stdlib.y +122 -0
  693. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/symbol.rb +105 -0
  694. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/symbols/resolver.rb +301 -0
  695. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/symbols.rb +3 -0
  696. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/type.rb +20 -0
  697. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/union.rb +12 -0
  698. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar.rb +407 -0
  699. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar_validator.rb +37 -0
  700. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/grammar_file.rb +40 -0
  701. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/location.rb +115 -0
  702. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/char.rb +11 -0
  703. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/ident.rb +11 -0
  704. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/instantiate_rule.rb +30 -0
  705. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/tag.rb +16 -0
  706. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/user_code.rb +83 -0
  707. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token.rb +70 -0
  708. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer.rb +191 -0
  709. data/ext/enclave/mruby/tools/lrama/lib/lrama/logger.rb +21 -0
  710. data/ext/enclave/mruby/tools/lrama/lib/lrama/option_parser.rb +169 -0
  711. data/ext/enclave/mruby/tools/lrama/lib/lrama/options.rb +28 -0
  712. data/ext/enclave/mruby/tools/lrama/lib/lrama/output.rb +459 -0
  713. data/ext/enclave/mruby/tools/lrama/lib/lrama/parser.rb +2144 -0
  714. data/ext/enclave/mruby/tools/lrama/lib/lrama/report/duration.rb +27 -0
  715. data/ext/enclave/mruby/tools/lrama/lib/lrama/report/profile.rb +16 -0
  716. data/ext/enclave/mruby/tools/lrama/lib/lrama/report.rb +4 -0
  717. data/ext/enclave/mruby/tools/lrama/lib/lrama/state/reduce.rb +37 -0
  718. data/ext/enclave/mruby/tools/lrama/lib/lrama/state/reduce_reduce_conflict.rb +11 -0
  719. data/ext/enclave/mruby/tools/lrama/lib/lrama/state/resolved_conflict.rb +31 -0
  720. data/ext/enclave/mruby/tools/lrama/lib/lrama/state/shift.rb +15 -0
  721. data/ext/enclave/mruby/tools/lrama/lib/lrama/state/shift_reduce_conflict.rb +11 -0
  722. data/ext/enclave/mruby/tools/lrama/lib/lrama/state.rb +433 -0
  723. data/ext/enclave/mruby/tools/lrama/lib/lrama/states/item.rb +91 -0
  724. data/ext/enclave/mruby/tools/lrama/lib/lrama/states.rb +595 -0
  725. data/ext/enclave/mruby/tools/lrama/lib/lrama/states_reporter.rb +362 -0
  726. data/ext/enclave/mruby/tools/lrama/lib/lrama/trace_reporter.rb +45 -0
  727. data/ext/enclave/mruby/tools/lrama/lib/lrama/version.rb +5 -0
  728. data/ext/enclave/mruby/tools/lrama/lib/lrama.rb +22 -0
  729. data/ext/enclave/mruby/tools/lrama/template/bison/_yacc.h +71 -0
  730. data/ext/enclave/mruby/tools/lrama/template/bison/yacc.c +2068 -0
  731. data/ext/enclave/mruby/tools/lrama/template/bison/yacc.h +40 -0
  732. data/ext/enclave/sandbox_build_config.rb +15 -0
  733. data/ext/enclave/sandbox_core.c +722 -0
  734. data/ext/enclave/sandbox_core.h +87 -0
  735. data/lib/enclave/result.rb +29 -0
  736. data/lib/enclave/tool.rb +38 -0
  737. data/lib/enclave/version.rb +3 -0
  738. data/lib/enclave.rb +73 -0
  739. metadata +819 -0
@@ -0,0 +1,2290 @@
1
+ #include <string.h>
2
+ #include <mruby.h>
3
+ #include <mruby/array.h>
4
+ #include <mruby/class.h>
5
+ #include <mruby/string.h>
6
+ #include <mruby/range.h>
7
+ #include <mruby/internal.h>
8
+ #include <mruby/presym.h>
9
+
10
+ #define ENC_ASCII_8BIT "ASCII-8BIT"
11
+ #define ENC_BINARY "BINARY"
12
+ #define ENC_UTF8 "UTF-8"
13
+
14
+ static mrb_value
15
+ int_chr_binary(mrb_state *mrb, mrb_value num)
16
+ {
17
+ mrb_int cp = mrb_as_int(mrb, num);
18
+
19
+ if (cp < 0 || 0xff < cp) {
20
+ mrb_raisef(mrb, E_RANGE_ERROR, "%v out of char range", num);
21
+ }
22
+ char c = (char)cp;
23
+ mrb_value str = mrb_str_new(mrb, &c, 1);
24
+ RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
25
+ return str;
26
+ }
27
+
28
+ #ifdef MRB_UTF8_STRING
29
+ static mrb_value
30
+ int_chr_utf8(mrb_state *mrb, mrb_value num)
31
+ {
32
+ mrb_int cp = mrb_int(mrb, num);
33
+ char utf8[4];
34
+ mrb_int len;
35
+ mrb_value str;
36
+
37
+ if (cp < 0 || 0x10FFFF < cp) {
38
+ mrb_raisef(mrb, E_RANGE_ERROR, "%v out of char range", num);
39
+ }
40
+ len = mrb_utf8_to_buf(utf8, (uint32_t)cp);
41
+ str = mrb_str_new(mrb, utf8, len);
42
+ if (len == 1) {
43
+ RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
44
+ }
45
+ return str;
46
+ }
47
+ #endif
48
+
49
+ /*
50
+ * call-seq:
51
+ * str.swapcase! -> str or nil
52
+ *
53
+ * Equivalent to `String#swapcase`, but modifies the receiver in
54
+ * place, returning *str*, or `nil` if no changes were made.
55
+ * Note: case conversion is effective only in ASCII region.
56
+ */
57
+ static mrb_value
58
+ str_swapcase_bang(mrb_state *mrb, mrb_value str)
59
+ {
60
+ int modify = 0;
61
+ struct RString *s = mrb_str_ptr(str);
62
+
63
+ mrb_str_modify(mrb, s);
64
+ char *p = RSTRING_PTR(str);
65
+ char *pend = p + RSTRING_LEN(str);
66
+ while (p < pend) {
67
+ if (ISUPPER(*p)) {
68
+ *p = TOLOWER(*p);
69
+ modify = 1;
70
+ }
71
+ else if (ISLOWER(*p)) {
72
+ *p = TOUPPER(*p);
73
+ modify = 1;
74
+ }
75
+ p++;
76
+ }
77
+
78
+ if (modify) return str;
79
+ return mrb_nil_value();
80
+ }
81
+
82
+ /*
83
+ * call-seq:
84
+ * str.swapcase -> new_str
85
+ *
86
+ * Returns a copy of *str* with uppercase alphabetic characters converted
87
+ * to lowercase and lowercase characters converted to uppercase.
88
+ * Note: case conversion is effective only in ASCII region.
89
+ *
90
+ * "Hello".swapcase #=> "hELLO"
91
+ * "cYbEr_PuNk11".swapcase #=> "CyBeR_pUnK11"
92
+ */
93
+ static mrb_value
94
+ str_swapcase(mrb_state *mrb, mrb_value self)
95
+ {
96
+ mrb_value str = mrb_str_dup(mrb, self);
97
+ str_swapcase_bang(mrb, str);
98
+ return str;
99
+ }
100
+
101
+ static void
102
+ str_concat(mrb_state *mrb, mrb_value self, mrb_value str, mrb_bool binary)
103
+ {
104
+ if (mrb_integer_p(str) || mrb_float_p(str)) {
105
+ #ifdef MRB_UTF8_STRING
106
+ if (binary) {
107
+ str = int_chr_binary(mrb, str);
108
+ }
109
+ else {
110
+ str = int_chr_utf8(mrb, str);
111
+ }
112
+ #else
113
+ str = int_chr_binary(mrb, str);
114
+ #endif
115
+ }
116
+ else
117
+ mrb_ensure_string_type(mrb, str);
118
+ mrb_str_cat_str(mrb, self, str);
119
+ }
120
+
121
+ static mrb_value
122
+ str_concat0(mrb_state *mrb, mrb_value self, mrb_bool binary)
123
+ {
124
+ if (mrb_get_argc(mrb) == 1) {
125
+ str_concat(mrb, self, mrb_get_arg1(mrb), binary);
126
+ return self;
127
+ }
128
+
129
+ mrb_value *args;
130
+ mrb_int alen;
131
+
132
+ mrb_get_args(mrb, "*", &args, &alen);
133
+ for (mrb_int i=0; i<alen; i++) {
134
+ str_concat(mrb, self, args[i], binary);
135
+ }
136
+ return self;
137
+ }
138
+
139
+ /*
140
+ * call-seq:
141
+ * str << obj -> str
142
+ * str.concat(*obj) -> str
143
+ *
144
+ * s = 'foo'
145
+ * s.concat('bar', 'baz') # => "foobarbaz"
146
+ * s # => "foobarbaz"
147
+ *
148
+ * For each given object `object` that is an \Integer,
149
+ * the value is considered a codepoint and converted to a character before concatenation:
150
+ *
151
+ * s = 'foo'
152
+ * s.concat(32, 'bar', 32, 'baz') # => "foo bar baz"
153
+ *
154
+ */
155
+ static mrb_value
156
+ str_concat_m(mrb_state *mrb, mrb_value self)
157
+ {
158
+ mrb_bool binary = RSTR_BINARY_P(mrb_str_ptr(self));
159
+ return str_concat0(mrb, self, binary);
160
+ }
161
+
162
+ /*
163
+ * call-seq:
164
+ * str.append_as_bytes(*obj) -> str
165
+ *
166
+ * Works like `concat` but consider arguments as binary strings.
167
+ *
168
+ */
169
+ static mrb_value
170
+ str_append_as_bytes(mrb_state *mrb, mrb_value self)
171
+ {
172
+ return str_concat0(mrb, self, TRUE);
173
+ }
174
+
175
+ /*
176
+ * call-seq:
177
+ * str.start_with?([prefixes]+) -> true or false
178
+ *
179
+ * Returns true if `str` starts with one of the `prefixes` given.
180
+ *
181
+ * "hello".start_with?("hell") #=> true
182
+ *
183
+ * # returns true if one of the prefixes matches.
184
+ * "hello".start_with?("heaven", "hell") #=> true
185
+ * "hello".start_with?("heaven", "paradise") #=> false
186
+ * "h".start_with?("heaven", "hell") #=> false
187
+ */
188
+ static mrb_value
189
+ str_start_with(mrb_state *mrb, mrb_value self)
190
+ {
191
+ const mrb_value *argv;
192
+ mrb_int argc;
193
+ mrb_get_args(mrb, "*", &argv, &argc);
194
+
195
+ for (mrb_int i = 0; i < argc; i++) {
196
+ int ai = mrb_gc_arena_save(mrb);
197
+ mrb_value sub = argv[i];
198
+ mrb_ensure_string_type(mrb, sub);
199
+ mrb_gc_arena_restore(mrb, ai);
200
+ size_t len_l = RSTRING_LEN(self);
201
+ size_t len_r = RSTRING_LEN(sub);
202
+ if (len_l >= len_r) {
203
+ if (memcmp(RSTRING_PTR(self), RSTRING_PTR(sub), len_r) == 0) {
204
+ return mrb_true_value();
205
+ }
206
+ }
207
+ }
208
+ return mrb_false_value();
209
+ }
210
+
211
+ /*
212
+ * call-seq:
213
+ * str.end_with?([suffixes]+) -> true or false
214
+ *
215
+ * Returns true if `str` ends with one of the `suffixes` given.
216
+ */
217
+ static mrb_value
218
+ str_end_with(mrb_state *mrb, mrb_value self)
219
+ {
220
+ const mrb_value *argv;
221
+ mrb_int argc;
222
+ mrb_get_args(mrb, "*", &argv, &argc);
223
+
224
+ for (mrb_int i = 0; i < argc; i++) {
225
+ int ai = mrb_gc_arena_save(mrb);
226
+ mrb_value sub = argv[i];
227
+ mrb_ensure_string_type(mrb, sub);
228
+ mrb_gc_arena_restore(mrb, ai);
229
+ size_t len_l = RSTRING_LEN(self);
230
+ size_t len_r = RSTRING_LEN(sub);
231
+ if (len_l >= len_r) {
232
+ if (memcmp(RSTRING_PTR(self) + (len_l - len_r),
233
+ RSTRING_PTR(sub),
234
+ len_r) == 0) {
235
+ return mrb_true_value();
236
+ }
237
+ }
238
+ }
239
+ return mrb_false_value();
240
+ }
241
+
242
+ enum tr_pattern_type {
243
+ TR_UNINITIALIZED = 0,
244
+ TR_IN_ORDER = 1,
245
+ TR_RANGE = 2,
246
+ };
247
+
248
+ /*
249
+ #tr Pattern syntax
250
+
251
+ <syntax> ::= (<pattern>)* | '^' (<pattern>)*
252
+ <pattern> ::= <in order> | <range>
253
+ <in order> ::= (<ch>)+
254
+ <range> ::= <ch> '-' <ch>
255
+ */
256
+ struct tr_pattern {
257
+ uint8_t type; // 1:in-order, 2:range
258
+ mrb_bool flag_reverse : 1;
259
+ mrb_bool flag_on_heap : 1;
260
+ uint16_t n;
261
+ union {
262
+ uint16_t start_pos;
263
+ char ch[2];
264
+ } val;
265
+ struct tr_pattern *next;
266
+ };
267
+
268
+ #define STATIC_TR_PATTERN { 0 }
269
+
270
+ static inline void
271
+ tr_free_pattern(mrb_state *mrb, struct tr_pattern *pat)
272
+ {
273
+ while (pat) {
274
+ struct tr_pattern *p = pat->next;
275
+ if (pat->flag_on_heap) {
276
+ mrb_free(mrb, pat);
277
+ }
278
+ pat = p;
279
+ }
280
+ }
281
+
282
+ static struct tr_pattern*
283
+ tr_parse_pattern(mrb_state *mrb, struct tr_pattern *ret, const mrb_value v_pattern, mrb_bool flag_reverse_enable, struct tr_pattern *pat0)
284
+ {
285
+ const char *pattern = RSTRING_PTR(v_pattern);
286
+ mrb_int pattern_length = RSTRING_LEN(v_pattern);
287
+ mrb_bool flag_reverse = FALSE;
288
+ mrb_int i = 0;
289
+
290
+ if (flag_reverse_enable && pattern_length >= 2 && pattern[0] == '^') {
291
+ flag_reverse = TRUE;
292
+ i++;
293
+ }
294
+
295
+ while (i < pattern_length) {
296
+ /* is range pattern ? */
297
+ mrb_bool const ret_uninit = (ret->type == TR_UNINITIALIZED);
298
+ struct tr_pattern *pat1 = ret_uninit ? ret
299
+ : (struct tr_pattern*)mrb_malloc_simple(mrb, sizeof(struct tr_pattern));
300
+ if (pat1 == NULL) {
301
+ if (pat0) tr_free_pattern(mrb, pat0);
302
+ tr_free_pattern(mrb, ret);
303
+ mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err));
304
+ return NULL; /* not reached */
305
+ }
306
+ if ((i+2) < pattern_length && pattern[i] != '\\' && pattern[i+1] == '-') {
307
+ pat1->type = TR_RANGE;
308
+ pat1->flag_reverse = flag_reverse;
309
+ pat1->flag_on_heap = !ret_uninit;
310
+ pat1->n = pattern[i+2] - pattern[i] + 1;
311
+ pat1->next = NULL;
312
+ pat1->val.ch[0] = pattern[i];
313
+ pat1->val.ch[1] = pattern[i+2];
314
+ i += 3;
315
+ }
316
+ else {
317
+ /* in order pattern. */
318
+ mrb_int start_pos = i++;
319
+
320
+ while (i < pattern_length) {
321
+ if ((i+2) < pattern_length && pattern[i] != '\\' && pattern[i+1] == '-')
322
+ break;
323
+ i++;
324
+ }
325
+
326
+ mrb_int len = i - start_pos;
327
+ if (len > UINT16_MAX) {
328
+ if (pat0) tr_free_pattern(mrb, pat0);
329
+ tr_free_pattern(mrb, ret);
330
+ if (ret != pat1) mrb_free(mrb, pat1);
331
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "tr pattern too long (max 65535)");
332
+ }
333
+ pat1->type = TR_IN_ORDER;
334
+ pat1->flag_reverse = flag_reverse;
335
+ pat1->flag_on_heap = !ret_uninit;
336
+ pat1->n = (uint16_t)len;
337
+ pat1->next = NULL;
338
+ pat1->val.start_pos = (uint16_t)start_pos;
339
+ }
340
+
341
+ if (!ret_uninit) {
342
+ struct tr_pattern *p = ret;
343
+ while (p->next != NULL) {
344
+ p = p->next;
345
+ }
346
+ p->next = pat1;
347
+ }
348
+ }
349
+
350
+ return ret;
351
+ }
352
+
353
+ static inline mrb_int
354
+ tr_find_character(const struct tr_pattern *pat, const char *pat_str, int ch)
355
+ {
356
+ mrb_int ret = -1;
357
+ mrb_int n_sum = 0;
358
+ mrb_int flag_reverse = pat ? pat->flag_reverse : 0;
359
+
360
+ while (pat != NULL) {
361
+ if (pat->type == TR_IN_ORDER) {
362
+ for (int i = 0; i < pat->n; i++) {
363
+ if (pat_str[pat->val.start_pos + i] == ch) ret = n_sum + i;
364
+ }
365
+ }
366
+ else if (pat->type == TR_RANGE) {
367
+ if (pat->val.ch[0] <= ch && ch <= pat->val.ch[1])
368
+ ret = n_sum + ch - pat->val.ch[0];
369
+ }
370
+ else {
371
+ mrb_assert(pat->type == TR_UNINITIALIZED);
372
+ }
373
+ n_sum += pat->n;
374
+ pat = pat->next;
375
+ }
376
+
377
+ if (flag_reverse) {
378
+ return (ret < 0) ? MRB_INT_MAX : -1;
379
+ }
380
+ return ret;
381
+ }
382
+
383
+ static inline mrb_int
384
+ tr_get_character(const struct tr_pattern *pat, const char *pat_str, mrb_int n_th)
385
+ {
386
+ mrb_int n_sum = 0;
387
+
388
+ while (pat != NULL) {
389
+ if (n_th < (n_sum + pat->n)) {
390
+ mrb_int i = (n_th - n_sum);
391
+
392
+ switch (pat->type) {
393
+ case TR_IN_ORDER:
394
+ return pat_str[pat->val.start_pos + i];
395
+ case TR_RANGE:
396
+ return pat->val.ch[0]+i;
397
+ case TR_UNINITIALIZED:
398
+ return -1;
399
+ }
400
+ }
401
+ if (pat->next == NULL) {
402
+ switch (pat->type) {
403
+ case TR_IN_ORDER:
404
+ return pat_str[pat->val.start_pos + pat->n - 1];
405
+ case TR_RANGE:
406
+ return pat->val.ch[1];
407
+ case TR_UNINITIALIZED:
408
+ return -1;
409
+ }
410
+ }
411
+ n_sum += pat->n;
412
+ pat = pat->next;
413
+ }
414
+
415
+ return -1;
416
+ }
417
+
418
+ static inline void
419
+ tr_bitmap_set(uint8_t bitmap[32], uint8_t ch)
420
+ {
421
+ uint8_t idx1 = ch / 8;
422
+ uint8_t idx2 = ch % 8;
423
+ bitmap[idx1] |= (1<<idx2);
424
+ }
425
+
426
+ static inline mrb_bool
427
+ tr_bitmap_detect(uint8_t bitmap[32], uint8_t ch)
428
+ {
429
+ uint8_t idx1 = ch / 8;
430
+ uint8_t idx2 = ch % 8;
431
+ if (bitmap[idx1] & (1<<idx2))
432
+ return TRUE;
433
+ return FALSE;
434
+ }
435
+
436
+ /* compile pattern to bitmap */
437
+ static void
438
+ tr_compile_pattern(const struct tr_pattern *pat, mrb_value pstr, uint8_t bitmap[32])
439
+ {
440
+ const char *pattern = RSTRING_PTR(pstr);
441
+ mrb_int flag_reverse = pat ? pat->flag_reverse : 0;
442
+ int i;
443
+
444
+ for (int i=0; i<32; i++) {
445
+ bitmap[i] = 0;
446
+ }
447
+ while (pat != NULL) {
448
+ if (pat->type == TR_IN_ORDER) {
449
+ for (i = 0; i < pat->n; i++) {
450
+ tr_bitmap_set(bitmap, pattern[pat->val.start_pos + i]);
451
+ }
452
+ }
453
+ else if (pat->type == TR_RANGE) {
454
+ for (i = pat->val.ch[0]; i < pat->val.ch[1]; i++) {
455
+ tr_bitmap_set(bitmap, i);
456
+ }
457
+ }
458
+ else {
459
+ mrb_assert(pat->type == TR_UNINITIALIZED);
460
+ }
461
+ pat = pat->next;
462
+ }
463
+
464
+ if (flag_reverse) {
465
+ for (i=0; i<32; i++) {
466
+ bitmap[i] ^= 0xff;
467
+ }
468
+ }
469
+ }
470
+
471
+ static mrb_bool
472
+ str_tr(mrb_state *mrb, mrb_value str, mrb_value p1, mrb_value p2, mrb_bool squeeze)
473
+ {
474
+ struct tr_pattern pat = STATIC_TR_PATTERN;
475
+ struct tr_pattern rep = STATIC_TR_PATTERN;
476
+ mrb_bool flag_changed = FALSE;
477
+ mrb_int lastch = -1;
478
+
479
+ mrb_str_modify(mrb, mrb_str_ptr(str));
480
+ tr_parse_pattern(mrb, &pat, p1, TRUE, NULL);
481
+ tr_parse_pattern(mrb, &rep, p2, FALSE, &pat);
482
+ char *s = RSTRING_PTR(str);
483
+ mrb_int len = RSTRING_LEN(str);
484
+
485
+ /* Hoist pointer retrieval outside loop to avoid repeated conditionals */
486
+ const char *p1_ptr = RSTRING_PTR(p1);
487
+ const char *p2_ptr = RSTRING_PTR(p2);
488
+ mrb_int i, j;
489
+ for (i=j=0; i<len; i++,j++) {
490
+ mrb_int n = tr_find_character(&pat, p1_ptr, s[i]);
491
+
492
+ if (i>j) s[j] = s[i];
493
+ if (n >= 0) {
494
+ flag_changed = TRUE;
495
+ mrb_int c = tr_get_character(&rep, p2_ptr, n);
496
+
497
+ if (c < 0 || (squeeze && c == lastch)) {
498
+ j--;
499
+ continue;
500
+ }
501
+ if (c > 0x80) {
502
+ tr_free_pattern(mrb, &pat);
503
+ tr_free_pattern(mrb, &rep);
504
+ mrb_raisef(mrb, E_ARGUMENT_ERROR, "character (%i) out of range", c);
505
+ }
506
+ lastch = c;
507
+ s[i] = (char)c;
508
+ }
509
+ }
510
+
511
+ tr_free_pattern(mrb, &pat);
512
+ tr_free_pattern(mrb, &rep);
513
+
514
+ if (flag_changed) {
515
+ RSTR_SET_LEN(RSTRING(str), j);
516
+ RSTRING_PTR(str)[j] = 0;
517
+ }
518
+ return flag_changed;
519
+ }
520
+
521
+ /*
522
+ * call-seq:
523
+ * str.tr(from_str, to_str) => new_str
524
+ *
525
+ * Returns a copy of str with the characters in from_str replaced by the
526
+ * corresponding characters in to_str. If to_str is shorter than from_str,
527
+ * it is padded with its last character in order to maintain the
528
+ * correspondence.
529
+ *
530
+ * "hello".tr('el', 'ip') #=> "hippo"
531
+ * "hello".tr('aeiou', '*') #=> "h*ll*"
532
+ * "hello".tr('aeiou', 'AA*') #=> "hAll*"
533
+ *
534
+ * Both strings may use the c1-c2 notation to denote ranges of characters,
535
+ * and from_str may start with a ^, which denotes all characters except
536
+ * those listed.
537
+ *
538
+ * "hello".tr('a-y', 'b-z') #=> "ifmmp"
539
+ * "hello".tr('^aeiou', '*') #=> "*e**o"
540
+ *
541
+ * The backslash character \ can be used to escape ^ or - and is otherwise
542
+ * ignored unless it appears at the end of a range or the end of the
543
+ * from_str or to_str:
544
+ *
545
+ *
546
+ * "hello^world".tr("\\^aeiou", "*") #=> "h*ll**w*rld"
547
+ * "hello-world".tr("a\\-eo", "*") #=> "h*ll**w*rld"
548
+ *
549
+ * "hello\r\nworld".tr("\r", "") #=> "hello\nworld"
550
+ * "hello\r\nworld".tr("\\r", "") #=> "hello\r\nwold"
551
+ * "hello\r\nworld".tr("\\\r", "") #=> "hello\nworld"
552
+ *
553
+ * "X['\\b']".tr("X\\", "") #=> "['b']"
554
+ * "X['\\b']".tr("X-\\]", "") #=> "'b'"
555
+ *
556
+ * Note: conversion is effective only in ASCII region.
557
+ */
558
+ static mrb_value
559
+ str_tr_m(mrb_state *mrb, mrb_value str)
560
+ {
561
+ mrb_value p1, p2;
562
+
563
+ mrb_get_args(mrb, "SS", &p1, &p2);
564
+ mrb_value dup = mrb_str_dup(mrb, str);
565
+ str_tr(mrb, dup, p1, p2, FALSE);
566
+ return dup;
567
+ }
568
+
569
+ /*
570
+ * call-seq:
571
+ * str.tr!(from_str, to_str) -> str or nil
572
+ *
573
+ * Translates str in place, using the same rules as String#tr.
574
+ * Returns str, or nil if no changes were made.
575
+ */
576
+ static mrb_value
577
+ str_tr_bang(mrb_state *mrb, mrb_value str)
578
+ {
579
+ mrb_value p1, p2;
580
+
581
+ mrb_get_args(mrb, "SS", &p1, &p2);
582
+ if (str_tr(mrb, str, p1, p2, FALSE)) {
583
+ return str;
584
+ }
585
+ return mrb_nil_value();
586
+ }
587
+
588
+ /*
589
+ * call-seq:
590
+ * str.tr_s(from_str, to_str) -> new_str
591
+ *
592
+ * Processes a copy of str as described under String#tr, then removes
593
+ * duplicate characters in regions that were affected by the translation.
594
+ *
595
+ * "hello".tr_s('l', 'r') #=> "hero"
596
+ * "hello".tr_s('el', '*') #=> "h*o"
597
+ * "hello".tr_s('el', 'hx') #=> "hhxo"
598
+ */
599
+ static mrb_value
600
+ str_tr_s(mrb_state *mrb, mrb_value str)
601
+ {
602
+ mrb_value p1, p2;
603
+
604
+ mrb_get_args(mrb, "SS", &p1, &p2);
605
+ mrb_value dup = mrb_str_dup(mrb, str);
606
+ str_tr(mrb, dup, p1, p2, TRUE);
607
+ return dup;
608
+ }
609
+
610
+ /*
611
+ * call-seq:
612
+ * str.tr_s!(from_str, to_str) -> str or nil
613
+ *
614
+ * Performs String#tr_s processing on str in place, returning
615
+ * str, or nil if no changes were made.
616
+ */
617
+ static mrb_value
618
+ str_tr_s_bang(mrb_state *mrb, mrb_value str)
619
+ {
620
+ mrb_value p1, p2;
621
+
622
+ mrb_get_args(mrb, "SS", &p1, &p2);
623
+ if (str_tr(mrb, str, p1, p2, TRUE)) {
624
+ return str;
625
+ }
626
+ return mrb_nil_value();
627
+ }
628
+
629
+ static mrb_bool
630
+ str_squeeze(mrb_state *mrb, mrb_value str, mrb_value v_pat)
631
+ {
632
+ struct tr_pattern pat_storage = STATIC_TR_PATTERN;
633
+ struct tr_pattern *pat = NULL;
634
+ mrb_int i, j;
635
+ mrb_bool flag_changed = FALSE;
636
+ mrb_int lastch = -1;
637
+ uint8_t bitmap[32];
638
+
639
+ mrb_str_modify(mrb, mrb_str_ptr(str));
640
+ if (!mrb_nil_p(v_pat)) {
641
+ pat = tr_parse_pattern(mrb, &pat_storage, v_pat, TRUE, NULL);
642
+ tr_compile_pattern(pat, v_pat, bitmap);
643
+ tr_free_pattern(mrb, pat);
644
+ }
645
+ char *s = RSTRING_PTR(str);
646
+ mrb_int len = RSTRING_LEN(str);
647
+
648
+ if (pat) {
649
+ for (i=j=0; i<len; i++,j++) {
650
+ if (i>j) s[j] = s[i];
651
+ if (tr_bitmap_detect(bitmap, s[i]) && s[i] == lastch) {
652
+ flag_changed = TRUE;
653
+ j--;
654
+ }
655
+ lastch = s[i];
656
+ }
657
+ }
658
+ else {
659
+ for (i=j=0; i<len; i++,j++) {
660
+ if (i>j) s[j] = s[i];
661
+ if (s[i] >= 0 && s[i] == lastch) {
662
+ flag_changed = TRUE;
663
+ j--;
664
+ }
665
+ lastch = s[i];
666
+ }
667
+ }
668
+
669
+ if (flag_changed) {
670
+ RSTR_SET_LEN(RSTRING(str), j);
671
+ RSTRING_PTR(str)[j] = 0;
672
+ }
673
+ return flag_changed;
674
+ }
675
+
676
+ /*
677
+ * call-seq:
678
+ * str.squeeze([other_str]) -> new_str
679
+ *
680
+ * Builds a set of characters from the other_str
681
+ * parameter(s) using the procedure described for String#count. Returns a
682
+ * new string where runs of the same character that occur in this set are
683
+ * replaced by a single character. If no arguments are given, all runs of
684
+ * identical characters are replaced by a single character.
685
+ *
686
+ * "yellow moon".squeeze #=> "yelow mon"
687
+ * " now is the".squeeze(" ") #=> " now is the"
688
+ * "putters shoot balls".squeeze("m-z") #=> "puters shot balls"
689
+ */
690
+ static mrb_value
691
+ str_squeeze_m(mrb_state *mrb, mrb_value str)
692
+ {
693
+ mrb_value pat = mrb_nil_value();
694
+
695
+ mrb_get_args(mrb, "|S", &pat);
696
+ mrb_value dup = mrb_str_dup(mrb, str);
697
+ str_squeeze(mrb, dup, pat);
698
+ return dup;
699
+ }
700
+
701
+ /*
702
+ * call-seq:
703
+ * str.squeeze!([other_str]) -> str or nil
704
+ *
705
+ * Squeezes str in place, returning either str, or nil if no
706
+ * changes were made.
707
+ */
708
+ static mrb_value
709
+ str_squeeze_bang(mrb_state *mrb, mrb_value str)
710
+ {
711
+ mrb_value pat = mrb_nil_value();
712
+
713
+ mrb_get_args(mrb, "|S", &pat);
714
+ if (str_squeeze(mrb, str, pat)) {
715
+ return str;
716
+ }
717
+ return mrb_nil_value();
718
+ }
719
+
720
+ static mrb_bool
721
+ str_delete(mrb_state *mrb, mrb_value str, mrb_value v_pat)
722
+ {
723
+ struct tr_pattern pat = STATIC_TR_PATTERN;
724
+ mrb_bool flag_changed = FALSE;
725
+ uint8_t bitmap[32];
726
+
727
+ mrb_str_modify(mrb, mrb_str_ptr(str));
728
+ tr_parse_pattern(mrb, &pat, v_pat, TRUE, NULL);
729
+ tr_compile_pattern(&pat, v_pat, bitmap);
730
+ tr_free_pattern(mrb, &pat);
731
+
732
+ char *s = RSTRING_PTR(str);
733
+ mrb_int len = RSTRING_LEN(str);
734
+ mrb_int i, j;
735
+
736
+ for (i=j=0; i<len; i++,j++) {
737
+ if (i>j) s[j] = s[i];
738
+ if (tr_bitmap_detect(bitmap, s[i])) {
739
+ flag_changed = TRUE;
740
+ j--;
741
+ }
742
+ }
743
+ if (flag_changed) {
744
+ RSTR_SET_LEN(RSTRING(str), j);
745
+ RSTRING_PTR(str)[j] = 0;
746
+ }
747
+ return flag_changed;
748
+ }
749
+
750
+ /* Internal helper for String#delete - returns new string with pattern characters removed */
751
+ static mrb_value
752
+ str_delete_m(mrb_state *mrb, mrb_value str)
753
+ {
754
+ mrb_value pat;
755
+
756
+ mrb_get_args(mrb, "S", &pat);
757
+ mrb_value dup = mrb_str_dup(mrb, str);
758
+ str_delete(mrb, dup, pat);
759
+ return dup;
760
+ }
761
+
762
+ /* Internal helper for String#delete! - removes pattern characters in place */
763
+ static mrb_value
764
+ str_delete_bang(mrb_state *mrb, mrb_value str)
765
+ {
766
+ mrb_value pat;
767
+
768
+ mrb_get_args(mrb, "S", &pat);
769
+ if (str_delete(mrb, str, pat)) {
770
+ return str;
771
+ }
772
+ return mrb_nil_value();
773
+ }
774
+
775
+ /*
776
+ * call_seq:
777
+ * str.count([other_str]) -> integer
778
+ *
779
+ * Each other_str parameter defines a set of characters to count. The
780
+ * intersection of these sets defines the characters to count in str. Any
781
+ * other_str that starts with a caret ^ is negated. The sequence c1-c2
782
+ * means all characters between c1 and c2. The backslash character \ can
783
+ * be used to escape ^ or - and is otherwise ignored unless it appears at
784
+ * the end of a sequence or the end of a other_str.
785
+ */
786
+ static mrb_value
787
+ str_count(mrb_state *mrb, mrb_value str)
788
+ {
789
+ mrb_value v_pat = mrb_nil_value();
790
+ struct tr_pattern pat = STATIC_TR_PATTERN;
791
+ uint8_t bitmap[32];
792
+
793
+ mrb_get_args(mrb, "S", &v_pat);
794
+ tr_parse_pattern(mrb, &pat, v_pat, TRUE, NULL);
795
+ tr_compile_pattern(&pat, v_pat, bitmap);
796
+ tr_free_pattern(mrb, &pat);
797
+
798
+ char *s = RSTRING_PTR(str);
799
+ mrb_int len = RSTRING_LEN(str);
800
+ mrb_int count = 0;
801
+ for (mrb_int i = 0; i < len; i++) {
802
+ if (tr_bitmap_detect(bitmap, s[i])) count++;
803
+ }
804
+ return mrb_fixnum_value(count);
805
+ }
806
+
807
+ /* Internal helper for String#hex - converts hex string to integer */
808
+ static mrb_value
809
+ str_hex(mrb_state *mrb, mrb_value self)
810
+ {
811
+ return mrb_str_to_integer(mrb, self, 16, FALSE);
812
+ }
813
+
814
+ /* Internal helper for String#oct - converts octal string to integer */
815
+ static mrb_value
816
+ str_oct(mrb_state *mrb, mrb_value self)
817
+ {
818
+ return mrb_str_to_integer(mrb, self, 8, FALSE);
819
+ }
820
+
821
+ /*
822
+ * call-seq:
823
+ * string.chr -> string
824
+ *
825
+ * Returns a one-character string at the beginning of the string.
826
+ *
827
+ * a = "abcde"
828
+ * a.chr #=> "a"
829
+ */
830
+ static mrb_value
831
+ str_chr(mrb_state *mrb, mrb_value self)
832
+ {
833
+ return mrb_str_substr(mrb, self, 0, 1);
834
+ }
835
+
836
+ /*
837
+ * call-seq:
838
+ * int.chr([encoding]) -> string
839
+ *
840
+ * Returns a string containing the character represented by the `int`'s value
841
+ * according to `encoding`. +"ASCII-8BIT"+ (+"BINARY"+) and +"UTF-8"+ (only
842
+ * with `MRB_UTF8_STRING`) can be specified as `encoding` (default is
843
+ * +"ASCII-8BIT"+).
844
+ *
845
+ * 65.chr #=> "A"
846
+ * 230.chr #=> "\xE6"
847
+ * 230.chr("ASCII-8BIT") #=> "\xE6"
848
+ * 230.chr("UTF-8") #=> "\u00E6"
849
+ */
850
+ static mrb_value
851
+ int_chr(mrb_state *mrb, mrb_value num)
852
+ {
853
+ mrb_value enc;
854
+ mrb_bool enc_given;
855
+
856
+ mrb_get_args(mrb, "|S?", &enc, &enc_given);
857
+ if (!enc_given ||
858
+ MRB_STR_CASECMP_P(enc, ENC_ASCII_8BIT) ||
859
+ MRB_STR_CASECMP_P(enc, ENC_BINARY)) {
860
+ return int_chr_binary(mrb, num);
861
+ }
862
+ #ifdef MRB_UTF8_STRING
863
+ else if (MRB_STR_CASECMP_P(enc, ENC_UTF8)) {
864
+ return int_chr_utf8(mrb, num);
865
+ }
866
+ #endif
867
+ else {
868
+ mrb_raisef(mrb, E_ARGUMENT_ERROR, "unknown encoding name - %v", enc);
869
+ }
870
+ /* not reached */
871
+ return mrb_nil_value();
872
+ }
873
+
874
+ /*
875
+ * call-seq:
876
+ * string.succ -> string
877
+ *
878
+ * Returns next sequence of the string;
879
+ *
880
+ * a = "bed"
881
+ * a.succ #=> "bee"
882
+ */
883
+ static mrb_value
884
+ str_succ_bang(mrb_state *mrb, mrb_value self)
885
+ {
886
+ mrb_value result;
887
+ const char *prepend;
888
+ struct RString *s = mrb_str_ptr(self);
889
+
890
+ if (RSTRING_LEN(self) == 0)
891
+ return self;
892
+
893
+ mrb_str_modify(mrb, s);
894
+ mrb_int l = RSTRING_LEN(self);
895
+ unsigned char *p, *e, *b, *t;
896
+ b = p = (unsigned char*) RSTRING_PTR(self);
897
+ t = e = p + l;
898
+ *(e--) = 0;
899
+
900
+ // find trailing ascii/number
901
+ while (e >= b) {
902
+ if (ISALNUM(*e))
903
+ break;
904
+ e--;
905
+ }
906
+ if (e < b) {
907
+ e = p + l - 1;
908
+ result = mrb_str_new_lit(mrb, "");
909
+ }
910
+ else {
911
+ // find leading letter of the ascii/number
912
+ b = e;
913
+ while (b > p) {
914
+ if (!ISALNUM(*b) || (ISALNUM(*b) && *b != '9' && *b != 'z' && *b != 'Z'))
915
+ break;
916
+ b--;
917
+ }
918
+ if (!ISALNUM(*b))
919
+ b++;
920
+ result = mrb_str_new(mrb, (char*) p, b - p);
921
+ }
922
+
923
+ while (e >= b) {
924
+ if (!ISALNUM(*e)) {
925
+ if (*e == 0xff) {
926
+ mrb_str_cat_lit(mrb, result, "\x01");
927
+ (*e) = 0;
928
+ }
929
+ else
930
+ (*e)++;
931
+ break;
932
+ }
933
+ prepend = NULL;
934
+ if (*e == '9') {
935
+ if (e == b) prepend = "1";
936
+ *e = '0';
937
+ }
938
+ else if (*e == 'z') {
939
+ if (e == b) prepend = "a";
940
+ *e = 'a';
941
+ }
942
+ else if (*e == 'Z') {
943
+ if (e == b) prepend = "A";
944
+ *e = 'A';
945
+ }
946
+ else {
947
+ (*e)++;
948
+ break;
949
+ }
950
+ if (prepend) mrb_str_cat_cstr(mrb, result, prepend);
951
+ e--;
952
+ }
953
+ result = mrb_str_cat(mrb, result, (char*) b, t - b);
954
+ l = RSTRING_LEN(result);
955
+ mrb_str_resize(mrb, self, l);
956
+ memcpy(RSTRING_PTR(self), RSTRING_PTR(result), l);
957
+ return self;
958
+ }
959
+
960
+ static mrb_value
961
+ str_succ(mrb_state *mrb, mrb_value self)
962
+ {
963
+ mrb_value str = mrb_str_dup(mrb, self);
964
+ str_succ_bang(mrb, str);
965
+ return str;
966
+ }
967
+
968
+ #ifdef MRB_UTF8_STRING
969
+ extern const char mrb_utf8len_table[];
970
+
971
+ MRB_INLINE mrb_int
972
+ utf8code(mrb_state* mrb, const unsigned char* p, const unsigned char *e)
973
+ {
974
+ if (p[0] < 0x80) return p[0];
975
+
976
+ mrb_int len = mrb_utf8len_table[p[0]>>3];
977
+ if (p+len <= e && len > 1 && (p[1] & 0xc0) == 0x80) {
978
+ if (len == 2)
979
+ return ((p[0] & 0x1f) << 6) + (p[1] & 0x3f);
980
+ if ((p[2] & 0xc0) == 0x80) {
981
+ if (len == 3)
982
+ return ((p[0] & 0x0f) << 12) + ((p[1] & 0x3f) << 6)
983
+ + (p[2] & 0x3f);
984
+ if ((p[3] & 0xc0) == 0x80) {
985
+ if (len == 4)
986
+ return ((p[0] & 0x07) << 18) + ((p[1] & 0x3f) << 12)
987
+ + ((p[2] & 0x3f) << 6) + (p[3] & 0x3f);
988
+ }
989
+ }
990
+ }
991
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid UTF-8 byte sequence");
992
+ /* not reached */
993
+ return -1;
994
+ }
995
+
996
+ static mrb_value
997
+ str_ord(mrb_state* mrb, mrb_value str)
998
+ {
999
+ struct RString *s = mrb_str_ptr(str);
1000
+ const unsigned char *p = (unsigned char*)RSTR_PTR(s);
1001
+ const unsigned char *e = p + RSTR_LEN(s);
1002
+ mrb_int c;
1003
+
1004
+ if (p == e) {
1005
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "empty string");
1006
+ }
1007
+ if (RSTR_SINGLE_BYTE_P(s) || RSTR_BINARY_P(s)) {
1008
+ c = p[0];
1009
+ }
1010
+ else {
1011
+ c = utf8code(mrb, p, e);
1012
+ }
1013
+ return mrb_fixnum_value(c);
1014
+ }
1015
+
1016
+ /* Internal helper for String#codepoints - returns array of character codepoints */
1017
+ static mrb_value
1018
+ str_codepoints(mrb_state *mrb, mrb_value str)
1019
+ {
1020
+ struct RString *s = mrb_str_ptr(str);
1021
+ const unsigned char *p = (unsigned char*)RSTR_PTR(s);
1022
+ const unsigned char *e = p + RSTR_LEN(s);
1023
+
1024
+ mrb->c->ci->mid = 0;
1025
+ mrb_value result = mrb_ary_new(mrb);
1026
+ if (RSTR_SINGLE_BYTE_P(s) || RSTR_BINARY_P(s)) {
1027
+ while (p < e) {
1028
+ mrb_ary_push(mrb, result, mrb_int_value(mrb, (mrb_int)*p));
1029
+ p++;
1030
+ }
1031
+ }
1032
+ else {
1033
+ while (p < e) {
1034
+ mrb_int c = utf8code(mrb, p, e);
1035
+ mrb_ary_push(mrb, result, mrb_int_value(mrb, c));
1036
+ p += mrb_utf8len_table[p[0]>>3];
1037
+ }
1038
+ }
1039
+ return result;
1040
+ }
1041
+ #else
1042
+ static mrb_value
1043
+ str_ord(mrb_state* mrb, mrb_value str)
1044
+ {
1045
+ if (RSTRING_LEN(str) == 0)
1046
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "empty string");
1047
+ return mrb_fixnum_value((unsigned char)RSTRING_PTR(str)[0]);
1048
+ }
1049
+
1050
+ static mrb_value
1051
+ str_codepoints(mrb_state *mrb, mrb_value self)
1052
+ {
1053
+ char *p = RSTRING_PTR(self);
1054
+ char *e = p + RSTRING_LEN(self);
1055
+
1056
+ mrb->c->ci->mid = 0;
1057
+ mrb_value result = mrb_ary_new(mrb);
1058
+ while (p < e) {
1059
+ mrb_ary_push(mrb, result, mrb_int_value(mrb, (mrb_int)*p));
1060
+ p++;
1061
+ }
1062
+ return result;
1063
+ }
1064
+ #endif
1065
+
1066
+ static mrb_bool
1067
+ str_prefix_p(mrb_state *mrb, mrb_value str, const char *prefix_ptr, mrb_int prefix_len)
1068
+ {
1069
+ mrb_int str_len = RSTRING_LEN(str);
1070
+ if (prefix_len > str_len) return FALSE;
1071
+ return memcmp(RSTRING_PTR(str), prefix_ptr, prefix_len) == 0;
1072
+ }
1073
+
1074
+ /*
1075
+ * call-seq:
1076
+ * str.delete_prefix!(prefix) -> self or nil
1077
+ *
1078
+ * Deletes leading `prefix` from *str*, returning
1079
+ * `nil` if no change was made.
1080
+ *
1081
+ * "hello".delete_prefix!("hel") #=> "lo"
1082
+ * "hello".delete_prefix!("llo") #=> nil
1083
+ */
1084
+ static mrb_value
1085
+ str_del_prefix_bang(mrb_state *mrb, mrb_value self)
1086
+ {
1087
+ mrb_int plen;
1088
+ const char *ptr;
1089
+
1090
+ mrb_get_args(mrb, "s", &ptr, &plen);
1091
+ struct RString *str = RSTRING(self);
1092
+ mrb_int slen = RSTR_LEN(str);
1093
+ if (plen > slen) return mrb_nil_value();
1094
+ char *s = RSTR_PTR(str);
1095
+ if (!str_prefix_p(mrb, self, ptr, plen)) return mrb_nil_value();
1096
+ if (!mrb_frozen_p(str) && (RSTR_SHARED_P(str) || RSTR_FSHARED_P(str))) {
1097
+ str->as.heap.ptr += plen;
1098
+ }
1099
+ else {
1100
+ mrb_str_modify(mrb, str);
1101
+ s = RSTR_PTR(str);
1102
+ memmove(s, s+plen, slen-plen);
1103
+ }
1104
+ RSTR_SET_LEN(str, slen-plen);
1105
+ return self;
1106
+ }
1107
+
1108
+ /*
1109
+ * call-seq:
1110
+ * str.delete_prefix(prefix) -> new_str
1111
+ *
1112
+ * Returns a copy of *str* with leading `prefix` deleted.
1113
+ *
1114
+ * "hello".delete_prefix("hel") #=> "lo"
1115
+ * "hello".delete_prefix("llo") #=> "hello"
1116
+ */
1117
+ static mrb_value
1118
+ str_del_prefix(mrb_state *mrb, mrb_value self)
1119
+ {
1120
+ mrb_int plen;
1121
+ const char *ptr;
1122
+
1123
+ mrb_get_args(mrb, "s", &ptr, &plen);
1124
+ mrb_int slen = RSTRING_LEN(self);
1125
+ if (plen > slen) return mrb_str_dup(mrb, self);
1126
+ if (!str_prefix_p(mrb, self, ptr, plen))
1127
+ return mrb_str_dup(mrb, self);
1128
+ return mrb_str_substr(mrb, self, plen, slen-plen);
1129
+ }
1130
+
1131
+ static mrb_bool
1132
+ str_suffix_p(mrb_state *mrb, mrb_value str, const char *suffix_ptr, mrb_int suffix_len)
1133
+ {
1134
+ mrb_int str_len = RSTRING_LEN(str);
1135
+ if (suffix_len > str_len) return FALSE;
1136
+ return memcmp(RSTRING_PTR(str) + (str_len - suffix_len), suffix_ptr, suffix_len) == 0;
1137
+ }
1138
+
1139
+ /*
1140
+ * call-seq:
1141
+ * str.delete_suffix!(suffix) -> self or nil
1142
+ *
1143
+ * Deletes trailing `suffix` from *str*, returning
1144
+ * `nil` if no change was made.
1145
+ *
1146
+ * "hello".delete_suffix!("llo") #=> "he"
1147
+ * "hello".delete_suffix!("hel") #=> nil
1148
+ */
1149
+ static mrb_value
1150
+ str_del_suffix_bang(mrb_state *mrb, mrb_value self)
1151
+ {
1152
+ mrb_int plen;
1153
+ const char *ptr;
1154
+
1155
+ mrb_get_args(mrb, "s", &ptr, &plen);
1156
+ struct RString *str = RSTRING(self);
1157
+ mrb_check_frozen(mrb, str);
1158
+ mrb_int slen = RSTR_LEN(str);
1159
+ if (plen > slen) return mrb_nil_value();
1160
+ if (!str_suffix_p(mrb, self, ptr, plen)) return mrb_nil_value();
1161
+ RSTR_SET_LEN(str, slen-plen);
1162
+ return self;
1163
+ }
1164
+
1165
+ /*
1166
+ * call-seq:
1167
+ * str.delete_suffix(suffix) -> new_str
1168
+ *
1169
+ * Returns a copy of *str* with leading `suffix` deleted.
1170
+ *
1171
+ * "hello".delete_suffix("hel") #=> "lo"
1172
+ * "hello".delete_suffix("llo") #=> "hello"
1173
+ */
1174
+ static mrb_value
1175
+ str_del_suffix(mrb_state *mrb, mrb_value self)
1176
+ {
1177
+ mrb_int plen;
1178
+ const char *ptr;
1179
+
1180
+ mrb_get_args(mrb, "s", &ptr, &plen);
1181
+ mrb_int slen = RSTRING_LEN(self);
1182
+ if (plen > slen) return mrb_str_dup(mrb, self);
1183
+ if (!str_suffix_p(mrb, self, ptr, plen))
1184
+ return mrb_str_dup(mrb, self);
1185
+ return mrb_str_substr(mrb, self, 0, slen-plen);
1186
+ }
1187
+
1188
+ #define lesser(a,b) (((a)>(b))?(b):(a))
1189
+
1190
+ /*
1191
+ * call-seq:
1192
+ * str.casecmp(other_str) -> -1, 0, +1 or nil
1193
+ *
1194
+ * Case-insensitive version of `String#<=>`.
1195
+ *
1196
+ * "abcdef".casecmp("abcde") #=> 1
1197
+ * "aBcDeF".casecmp("abcdef") #=> 0
1198
+ * "abcdef".casecmp("abcdefg") #=> -1
1199
+ * "abcdef".casecmp("ABCDEF") #=> 0
1200
+ */
1201
+ static mrb_value
1202
+ str_casecmp(mrb_state *mrb, mrb_value self)
1203
+ {
1204
+ mrb_value str = mrb_get_arg1(mrb);
1205
+
1206
+ if (!mrb_string_p(str)) return mrb_nil_value();
1207
+
1208
+ struct RString *s1 = mrb_str_ptr(self);
1209
+ struct RString *s2 = mrb_str_ptr(str);
1210
+
1211
+ mrb_int len1 = RSTR_LEN(s1);
1212
+ mrb_int len2 = RSTR_LEN(s2);
1213
+ mrb_int len = lesser(len1, len2);
1214
+ char *p1 = RSTR_PTR(s1);
1215
+ char *p2 = RSTR_PTR(s2);
1216
+ if (p1 == p2) return mrb_fixnum_value(0);
1217
+
1218
+ for (mrb_int i=0; i<len; i++) {
1219
+ int c1 = p1[i], c2 = p2[i];
1220
+ if (ISASCII(c1) && ISUPPER(c1)) c1 = TOLOWER(c1);
1221
+ if (ISASCII(c2) && ISUPPER(c2)) c2 = TOLOWER(c2);
1222
+ if (c1 > c2) return mrb_fixnum_value(1);
1223
+ if (c1 < c2) return mrb_fixnum_value(-1);
1224
+ }
1225
+ if (len1 == len2) return mrb_fixnum_value(0);
1226
+ if (len1 > len2) return mrb_fixnum_value(1);
1227
+ return mrb_fixnum_value(-1);
1228
+ }
1229
+ #undef lesser
1230
+
1231
+ /*
1232
+ * call-seq:
1233
+ * str.casecmp?(other) -> true, false, or nil
1234
+ *
1235
+ * Returns true if str and other_str are equal after case folding,
1236
+ * false if they are not equal, and nil if other is not a string.
1237
+ */
1238
+ static mrb_value
1239
+ str_casecmp_p(mrb_state *mrb, mrb_value self)
1240
+ {
1241
+ mrb_value c = str_casecmp(mrb, self);
1242
+ if (mrb_nil_p(c)) return c;
1243
+ return mrb_bool_value(mrb_fixnum(c) == 0);
1244
+ }
1245
+
1246
+ /* Internal helper for String#lines - splits string into array of lines */
1247
+ static mrb_value
1248
+ str_lines(mrb_state *mrb, mrb_value self)
1249
+ {
1250
+ char *b = RSTRING_PTR(self);
1251
+ char *p = b, *t;
1252
+ char *e = b + RSTRING_LEN(self);
1253
+
1254
+ mrb->c->ci->mid = 0;
1255
+ mrb_value result = mrb_ary_new(mrb);
1256
+ int ai = mrb_gc_arena_save(mrb);
1257
+ while (p < e) {
1258
+ t = p;
1259
+ while (p < e && *p != '\n') p++;
1260
+ if (*p == '\n') p++;
1261
+ mrb_int len = (mrb_int) (p - t);
1262
+ mrb_ary_push(mrb, result, mrb_str_new(mrb, t, len));
1263
+ mrb_gc_arena_restore(mrb, ai);
1264
+ }
1265
+ return result;
1266
+ }
1267
+
1268
+ /*
1269
+ * call-seq:
1270
+ * +string -> new_string or self
1271
+ *
1272
+ * Returns `self` if `self` is not frozen.
1273
+ *
1274
+ * Otherwise returns `self.dup`, which is not frozen.
1275
+ */
1276
+ static mrb_value
1277
+ str_uplus(mrb_state *mrb, mrb_value str)
1278
+ {
1279
+ if (mrb_frozen_p(mrb_obj_ptr(str))) {
1280
+ return mrb_str_dup(mrb, str);
1281
+ }
1282
+ else {
1283
+ return str;
1284
+ }
1285
+ }
1286
+
1287
+ /*
1288
+ * call-seq:
1289
+ * -string -> frozen_string
1290
+ *
1291
+ * Returns a frozen, possibly pre-existing copy of the string.
1292
+ *
1293
+ */
1294
+ static mrb_value
1295
+ str_uminus(mrb_state *mrb, mrb_value str)
1296
+ {
1297
+ if (mrb_frozen_p(mrb_obj_ptr(str))) {
1298
+ return str;
1299
+ }
1300
+ return mrb_obj_freeze(mrb, mrb_str_dup(mrb, str));
1301
+ }
1302
+
1303
+ /* Internal helper for String#ascii_only? - checks if string contains only ASCII characters */
1304
+ static mrb_value
1305
+ str_ascii_only_p(mrb_state *mrb, mrb_value str)
1306
+ {
1307
+ struct RString *s = mrb_str_ptr(str);
1308
+ const char *p = RSTR_PTR(s);
1309
+ const char *e = p + RSTR_LEN(s);
1310
+
1311
+ while (p < e) {
1312
+ if (*p & 0x80) return mrb_false_value();
1313
+ p++;
1314
+ }
1315
+ mrb_str_ptr(str)->flags |= MRB_STR_SINGLE_BYTE;
1316
+ return mrb_true_value();
1317
+ }
1318
+
1319
+ /* Internal helper for String#b - returns binary encoded copy of string */
1320
+ static mrb_value
1321
+ str_b(mrb_state *mrb, mrb_value self)
1322
+ {
1323
+ mrb_value str = mrb_str_dup(mrb, self);
1324
+ mrb_str_ptr(str)->flags |= MRB_STR_BINARY;
1325
+ return str;
1326
+ }
1327
+
1328
+ /*
1329
+ * Check if character is whitespace (space, tab, newline, carriage return, form feed, vertical tab)
1330
+ */
1331
+ static inline mrb_bool
1332
+ is_whitespace(char c)
1333
+ {
1334
+ return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v');
1335
+ }
1336
+
1337
+ /*
1338
+ * Check if character is whitespace or null (for rstrip)
1339
+ */
1340
+ static inline mrb_bool
1341
+ is_whitespace_or_null(char c)
1342
+ {
1343
+ return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v' || c == '\0');
1344
+ }
1345
+
1346
+ /*
1347
+ * call-seq:
1348
+ * str.lstrip -> new_str
1349
+ *
1350
+ * Returns a copy of str with leading whitespace removed.
1351
+ *
1352
+ * " hello ".lstrip #=> "hello "
1353
+ * "hello".lstrip #=> "hello"
1354
+ */
1355
+ static mrb_value
1356
+ str_lstrip(mrb_state *mrb, mrb_value self)
1357
+ {
1358
+ struct RString *s = mrb_str_ptr(self);
1359
+ const char *ptr = RSTR_PTR(s);
1360
+ mrb_int len = RSTR_LEN(s);
1361
+ mrb_int start = 0;
1362
+
1363
+ /* Find first non-whitespace character */
1364
+ while (start < len && is_whitespace(ptr[start])) {
1365
+ start++;
1366
+ }
1367
+
1368
+ /* Return empty string if all whitespace */
1369
+ if (start >= len) {
1370
+ return mrb_str_new_lit(mrb, "");
1371
+ }
1372
+
1373
+ /* Return substring from first non-whitespace to end */
1374
+ return mrb_str_substr(mrb, self, start, len - start);
1375
+ }
1376
+
1377
+ /*
1378
+ * call-seq:
1379
+ * str.rstrip -> new_str
1380
+ *
1381
+ * Returns a copy of str with trailing whitespace removed.
1382
+ *
1383
+ * " hello ".rstrip #=> " hello"
1384
+ * "hello".rstrip #=> "hello"
1385
+ */
1386
+ static mrb_value
1387
+ str_rstrip(mrb_state *mrb, mrb_value self)
1388
+ {
1389
+ struct RString *s = mrb_str_ptr(self);
1390
+ const char *ptr = RSTR_PTR(s);
1391
+ mrb_int len = RSTR_LEN(s);
1392
+ mrb_int end = len;
1393
+
1394
+ /* Find last non-whitespace character */
1395
+ while (end > 0 && is_whitespace_or_null(ptr[end - 1])) {
1396
+ end--;
1397
+ }
1398
+
1399
+ /* Return empty string if all whitespace */
1400
+ if (end <= 0) {
1401
+ return mrb_str_new_lit(mrb, "");
1402
+ }
1403
+
1404
+ /* Return substring from start to last non-whitespace */
1405
+ return mrb_str_substr(mrb, self, 0, end);
1406
+ }
1407
+
1408
+ /*
1409
+ * call-seq:
1410
+ * str.strip -> new_str
1411
+ *
1412
+ * Returns a copy of str with leading and trailing whitespace removed.
1413
+ *
1414
+ * " hello ".strip #=> "hello"
1415
+ * "\tgoodbye\r\n".strip #=> "goodbye"
1416
+ */
1417
+ static mrb_value
1418
+ str_strip(mrb_state *mrb, mrb_value self)
1419
+ {
1420
+ struct RString *s = mrb_str_ptr(self);
1421
+ const char *ptr = RSTR_PTR(s);
1422
+ mrb_int len = RSTR_LEN(s);
1423
+ mrb_int start = 0;
1424
+ mrb_int end = len;
1425
+
1426
+ /* Find first non-whitespace character */
1427
+ while (start < len && is_whitespace(ptr[start])) {
1428
+ start++;
1429
+ }
1430
+
1431
+ /* Find last non-whitespace character */
1432
+ while (end > start && is_whitespace_or_null(ptr[end - 1])) {
1433
+ end--;
1434
+ }
1435
+
1436
+ /* Return empty string if all whitespace */
1437
+ if (start >= end) {
1438
+ return mrb_str_new_lit(mrb, "");
1439
+ }
1440
+
1441
+ /* Return substring from first to last non-whitespace */
1442
+ return mrb_str_substr(mrb, self, start, end - start);
1443
+ }
1444
+
1445
+ /*
1446
+ * call-seq:
1447
+ * str.lstrip! -> self or nil
1448
+ *
1449
+ * Removes leading whitespace from str, returning nil if no change was made.
1450
+ *
1451
+ * " hello ".lstrip! #=> "hello "
1452
+ * "hello".lstrip! #=> nil
1453
+ */
1454
+ static mrb_value
1455
+ str_lstrip_bang(mrb_state *mrb, mrb_value self)
1456
+ {
1457
+ struct RString *s = mrb_str_ptr(self);
1458
+ char *ptr = RSTR_PTR(s);
1459
+ mrb_int len = RSTR_LEN(s);
1460
+ mrb_int start = 0;
1461
+
1462
+ mrb_check_frozen(mrb, mrb_obj_ptr(self));
1463
+ mrb_str_modify(mrb, s);
1464
+
1465
+ /* Find first non-whitespace character */
1466
+ while (start < len && is_whitespace(ptr[start])) {
1467
+ start++;
1468
+ }
1469
+
1470
+ /* No change needed */
1471
+ if (start == 0) {
1472
+ return mrb_nil_value();
1473
+ }
1474
+
1475
+ /* Move remaining characters to beginning */
1476
+ if (start < len) {
1477
+ memmove(ptr, ptr + start, len - start);
1478
+ RSTR_SET_LEN(s, len - start);
1479
+ ptr[len - start] = '\0';
1480
+ }
1481
+ else {
1482
+ /* All whitespace - make empty */
1483
+ RSTR_SET_LEN(s, 0);
1484
+ ptr[0] = '\0';
1485
+ }
1486
+
1487
+ return self;
1488
+ }
1489
+
1490
+ /*
1491
+ * call-seq:
1492
+ * str.rstrip! -> self or nil
1493
+ *
1494
+ * Removes trailing whitespace from str, returning nil if no change was made.
1495
+ *
1496
+ * " hello ".rstrip! #=> " hello"
1497
+ * "hello".rstrip! #=> nil
1498
+ */
1499
+ static mrb_value
1500
+ str_rstrip_bang(mrb_state *mrb, mrb_value self)
1501
+ {
1502
+ struct RString *s = mrb_str_ptr(self);
1503
+ char *ptr = RSTR_PTR(s);
1504
+ mrb_int len = RSTR_LEN(s);
1505
+ mrb_int end = len;
1506
+
1507
+ mrb_check_frozen(mrb, mrb_obj_ptr(self));
1508
+ mrb_str_modify(mrb, s);
1509
+
1510
+ /* Find last non-whitespace character */
1511
+ while (end > 0 && is_whitespace_or_null(ptr[end - 1])) {
1512
+ end--;
1513
+ }
1514
+
1515
+ /* No change needed */
1516
+ if (end == len) {
1517
+ return mrb_nil_value();
1518
+ }
1519
+
1520
+ /* Truncate string */
1521
+ RSTR_SET_LEN(s, end);
1522
+ ptr[end] = '\0';
1523
+
1524
+ return self;
1525
+ }
1526
+
1527
+ /*
1528
+ * call-seq:
1529
+ * str.strip! -> self or nil
1530
+ *
1531
+ * Removes leading and trailing whitespace from str, returning nil if no change was made.
1532
+ *
1533
+ * " hello ".strip! #=> "hello"
1534
+ * "hello".strip! #=> nil
1535
+ */
1536
+ static mrb_value
1537
+ str_strip_bang(mrb_state *mrb, mrb_value self)
1538
+ {
1539
+ struct RString *s = mrb_str_ptr(self);
1540
+ char *ptr = RSTR_PTR(s);
1541
+ mrb_int len = RSTR_LEN(s);
1542
+ mrb_int start = 0;
1543
+ mrb_int end = len;
1544
+ mrb_bool changed = FALSE;
1545
+
1546
+ mrb_check_frozen(mrb, mrb_obj_ptr(self));
1547
+ mrb_str_modify(mrb, s);
1548
+
1549
+ /* Find first non-whitespace character */
1550
+ while (start < len && is_whitespace(ptr[start])) {
1551
+ start++;
1552
+ }
1553
+
1554
+ /* Find last non-whitespace character */
1555
+ while (end > start && is_whitespace_or_null(ptr[end - 1])) {
1556
+ end--;
1557
+ }
1558
+
1559
+ /* Check if any changes needed */
1560
+ if (start > 0) {
1561
+ changed = TRUE;
1562
+ if (start < end) {
1563
+ memmove(ptr, ptr + start, end - start);
1564
+ }
1565
+ }
1566
+
1567
+ if (end != len) {
1568
+ changed = TRUE;
1569
+ }
1570
+
1571
+ if (!changed) {
1572
+ return mrb_nil_value();
1573
+ }
1574
+
1575
+ /* Set new length */
1576
+ RSTR_SET_LEN(s, end - start);
1577
+ ptr[end - start] = '\0';
1578
+
1579
+ return self;
1580
+ }
1581
+
1582
+ /* Internal helper to count UTF-8 characters in a string using mruby's standard function */
1583
+ static mrb_int
1584
+ str_char_count(mrb_value str)
1585
+ {
1586
+ #ifdef MRB_UTF8_STRING
1587
+ struct RString *s = mrb_str_ptr(str);
1588
+
1589
+ if (RSTR_SINGLE_BYTE_P(s) || RSTR_BINARY_P(s)) {
1590
+ /* ASCII/Binary: each byte is a character */
1591
+ return RSTR_LEN(s);
1592
+ }
1593
+
1594
+ /* UTF-8: use mruby's standard UTF-8 character counting function */
1595
+ return mrb_utf8_strlen(RSTR_PTR(s), RSTR_LEN(s));
1596
+ #else
1597
+ /* Non-UTF8 build: treat as single bytes */
1598
+ return RSTRING_LEN(str);
1599
+ #endif
1600
+ }
1601
+
1602
+ /* Internal fast path for String#chars - returns array of individual characters */
1603
+ static mrb_value
1604
+ str_chars_ary(mrb_state *mrb, mrb_value self)
1605
+ {
1606
+ struct RString *s = mrb_str_ptr(self);
1607
+ const unsigned char *p = (unsigned char*)RSTR_PTR(s);
1608
+ const unsigned char *e = p + RSTR_LEN(s);
1609
+
1610
+ /* Estimate character count for array pre-allocation */
1611
+ mrb_int estimated_chars = RSTR_LEN(s);
1612
+ if (!RSTR_SINGLE_BYTE_P(s) && !RSTR_BINARY_P(s)) {
1613
+ estimated_chars = estimated_chars / 2; /* rough estimate for UTF-8 */
1614
+ }
1615
+ mrb_value result = mrb_ary_new_capa(mrb, estimated_chars);
1616
+
1617
+ if (RSTR_SINGLE_BYTE_P(s) || RSTR_BINARY_P(s)) {
1618
+ /* ASCII/Binary: each byte is a character */
1619
+ while (p < e) {
1620
+ mrb_value char_str = mrb_str_new(mrb, (char*)p, 1);
1621
+ mrb_ary_push(mrb, result, char_str);
1622
+ p++;
1623
+ }
1624
+ }
1625
+ else {
1626
+ #ifdef MRB_UTF8_STRING
1627
+ /* UTF-8: handle multi-byte characters */
1628
+ while (p < e) {
1629
+ mrb_int char_len = mrb_utf8len_table[p[0] >> 3];
1630
+ if (char_len == 0 || char_len > 4 || p + char_len > e) {
1631
+ /* Invalid UTF-8, treat as single byte */
1632
+ char_len = 1;
1633
+ }
1634
+ else {
1635
+ /* Validate UTF-8 sequence */
1636
+ mrb_bool valid = TRUE;
1637
+ if (char_len > 1) {
1638
+ for (mrb_int i = 1; i < char_len; i++) {
1639
+ if ((p[i] & 0xC0) != 0x80) {
1640
+ valid = FALSE;
1641
+ break;
1642
+ }
1643
+ }
1644
+ }
1645
+ if (!valid) {
1646
+ char_len = 1;
1647
+ }
1648
+ }
1649
+ mrb_value char_str = mrb_str_new(mrb, (char*)p, char_len);
1650
+ mrb_ary_push(mrb, result, char_str);
1651
+ p += char_len;
1652
+ }
1653
+ #else
1654
+ /* Non-UTF8 build: treat as single bytes */
1655
+ while (p < e) {
1656
+ mrb_value char_str = mrb_str_new(mrb, (char*)p, 1);
1657
+ mrb_ary_push(mrb, result, char_str);
1658
+ p++;
1659
+ }
1660
+ #endif
1661
+ }
1662
+
1663
+ return result;
1664
+ }
1665
+
1666
+ /*
1667
+ * call-seq:
1668
+ * str.ljust(integer, padstr=' ') -> new_str
1669
+ *
1670
+ * If integer is greater than the length of str, returns a new
1671
+ * String of length integer with str left justified and padded with padstr;
1672
+ * otherwise, returns str.
1673
+ */
1674
+ static mrb_value
1675
+ str_ljust_core(mrb_state *mrb, mrb_value self)
1676
+ {
1677
+ mrb_int width;
1678
+ mrb_value padstr = mrb_str_new_lit(mrb, " ");
1679
+
1680
+ mrb_get_args(mrb, "i|S", &width, &padstr);
1681
+
1682
+ if (RSTRING_LEN(padstr) == 0) {
1683
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "zero width padding");
1684
+ }
1685
+
1686
+ mrb_int char_len = str_char_count(self);
1687
+ if (width <= char_len) {
1688
+ return mrb_str_dup(mrb, self);
1689
+ }
1690
+
1691
+ mrb_int padsize = width - char_len;
1692
+ mrb_int pad_char_len = str_char_count(padstr);
1693
+ if (pad_char_len == 0) {
1694
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "zero width padding");
1695
+ }
1696
+
1697
+ /* Build padding string by repeating padstr */
1698
+ mrb_value padding = mrb_str_new_lit(mrb, "");
1699
+ mrb_int chars_needed = padsize;
1700
+ while (chars_needed > 0) {
1701
+ if (chars_needed >= pad_char_len) {
1702
+ mrb_str_cat_str(mrb, padding, padstr);
1703
+ chars_needed -= pad_char_len;
1704
+ }
1705
+ else {
1706
+ /* Need partial padding - use substr to get exact characters */
1707
+ mrb_value partial = mrb_str_substr(mrb, padstr, 0, chars_needed);
1708
+ mrb_str_cat_str(mrb, padding, partial);
1709
+ chars_needed = 0;
1710
+ }
1711
+ }
1712
+
1713
+ return mrb_str_cat_str(mrb, mrb_str_dup(mrb, self), padding);
1714
+ }
1715
+
1716
+ /*
1717
+ * call-seq:
1718
+ * str.rjust(integer, padstr=' ') -> new_str
1719
+ *
1720
+ * If integer is greater than the length of str, returns a new
1721
+ * String of length integer with str right justified and padded with padstr;
1722
+ * otherwise, returns str.
1723
+ */
1724
+ static mrb_value
1725
+ str_rjust_core(mrb_state *mrb, mrb_value self)
1726
+ {
1727
+ mrb_int width;
1728
+ mrb_value padstr = mrb_str_new_lit(mrb, " ");
1729
+
1730
+ mrb_get_args(mrb, "i|S", &width, &padstr);
1731
+
1732
+ if (RSTRING_LEN(padstr) == 0) {
1733
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "zero width padding");
1734
+ }
1735
+
1736
+ mrb_int char_len = str_char_count(self);
1737
+ if (width <= char_len) {
1738
+ return mrb_str_dup(mrb, self);
1739
+ }
1740
+
1741
+ mrb_int padsize = width - char_len;
1742
+ mrb_int pad_char_len = str_char_count(padstr);
1743
+ if (pad_char_len == 0) {
1744
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "zero width padding");
1745
+ }
1746
+
1747
+ /* Build padding string by repeating padstr */
1748
+ mrb_value padding = mrb_str_new_lit(mrb, "");
1749
+ mrb_int chars_needed = padsize;
1750
+ while (chars_needed > 0) {
1751
+ if (chars_needed >= pad_char_len) {
1752
+ mrb_str_cat_str(mrb, padding, padstr);
1753
+ chars_needed -= pad_char_len;
1754
+ }
1755
+ else {
1756
+ /* Need partial padding - use substr to get exact characters */
1757
+ mrb_value partial = mrb_str_substr(mrb, padstr, 0, chars_needed);
1758
+ mrb_str_cat_str(mrb, padding, partial);
1759
+ chars_needed = 0;
1760
+ }
1761
+ }
1762
+
1763
+ return mrb_str_cat_str(mrb, padding, self);
1764
+ }
1765
+
1766
+ /*
1767
+ * call-seq:
1768
+ * str.center(width, padstr=' ') -> new_str
1769
+ *
1770
+ * Centers str in width. If width is greater than the length of str,
1771
+ * returns a new String of length width with str centered and padded with
1772
+ * padstr; otherwise, returns str.
1773
+ */
1774
+ static mrb_value
1775
+ str_center_core(mrb_state *mrb, mrb_value self)
1776
+ {
1777
+ mrb_int width;
1778
+ mrb_value padstr = mrb_str_new_lit(mrb, " ");
1779
+
1780
+ mrb_get_args(mrb, "i|S", &width, &padstr);
1781
+
1782
+ if (RSTRING_LEN(padstr) == 0) {
1783
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "zero width padding");
1784
+ }
1785
+
1786
+ mrb_int char_len = str_char_count(self);
1787
+ if (width <= char_len) {
1788
+ return mrb_str_dup(mrb, self);
1789
+ }
1790
+
1791
+ mrb_int total_pad = width - char_len;
1792
+ mrb_int left_pad = total_pad / 2;
1793
+ mrb_int right_pad = total_pad - left_pad;
1794
+
1795
+ mrb_int pad_char_len = str_char_count(padstr);
1796
+ if (pad_char_len == 0) {
1797
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "zero width padding");
1798
+ }
1799
+
1800
+ /* Build left padding */
1801
+ mrb_value left_padding = mrb_str_new_lit(mrb, "");
1802
+ mrb_int chars_needed = left_pad;
1803
+ while (chars_needed > 0) {
1804
+ if (chars_needed >= pad_char_len) {
1805
+ mrb_str_cat_str(mrb, left_padding, padstr);
1806
+ chars_needed -= pad_char_len;
1807
+ }
1808
+ else {
1809
+ mrb_value partial = mrb_str_substr(mrb, padstr, 0, chars_needed);
1810
+ mrb_str_cat_str(mrb, left_padding, partial);
1811
+ chars_needed = 0;
1812
+ }
1813
+ }
1814
+
1815
+ /* Build right padding */
1816
+ mrb_value right_padding = mrb_str_new_lit(mrb, "");
1817
+ chars_needed = right_pad;
1818
+ while (chars_needed > 0) {
1819
+ if (chars_needed >= pad_char_len) {
1820
+ mrb_str_cat_str(mrb, right_padding, padstr);
1821
+ chars_needed -= pad_char_len;
1822
+ }
1823
+ else {
1824
+ mrb_value partial = mrb_str_substr(mrb, padstr, 0, chars_needed);
1825
+ mrb_str_cat_str(mrb, right_padding, partial);
1826
+ chars_needed = 0;
1827
+ }
1828
+ }
1829
+
1830
+ mrb_value result = mrb_str_cat_str(mrb, left_padding, self);
1831
+ return mrb_str_cat_str(mrb, result, right_padding);
1832
+ }
1833
+
1834
+ #ifdef MRB_UTF8_STRING
1835
+ /*
1836
+ * Given a character index, find the byte offset in a UTF-8 string.
1837
+ * Returns -1 if the character index is out of bounds.
1838
+ */
1839
+ static mrb_int
1840
+ str_char_to_byte_offset(mrb_value str, mrb_int char_index)
1841
+ {
1842
+ struct RString *s = mrb_str_ptr(str);
1843
+ const char *p = RSTR_PTR(s);
1844
+ mrb_int byte_len = RSTR_LEN(s);
1845
+
1846
+ if (RSTR_SINGLE_BYTE_P(s) || RSTR_BINARY_P(s)) {
1847
+ return char_index;
1848
+ }
1849
+
1850
+ if (char_index < 0) return -1;
1851
+
1852
+ mrb_int byte_offset = 0;
1853
+ mrb_int current_char_index = 0;
1854
+ while (byte_offset < byte_len && current_char_index < char_index) {
1855
+ mrb_int char_len = mrb_utf8len(p + byte_offset, p + byte_len - byte_offset);
1856
+ if (char_len == 0) break;
1857
+ byte_offset += char_len;
1858
+ current_char_index++;
1859
+ }
1860
+
1861
+ if (current_char_index < char_index) return -1;
1862
+ return byte_offset;
1863
+ }
1864
+
1865
+ /*
1866
+ * Given a starting character index and a character length, find the byte length.
1867
+ */
1868
+ static mrb_int
1869
+ str_chars_to_byte_len(mrb_value str, mrb_int char_start, mrb_int char_len)
1870
+ {
1871
+ struct RString *s = mrb_str_ptr(str);
1872
+ const char *p = RSTR_PTR(s);
1873
+ mrb_int str_byte_len = RSTR_LEN(s);
1874
+
1875
+ if (RSTR_SINGLE_BYTE_P(s) || RSTR_BINARY_P(s)) {
1876
+ return char_len;
1877
+ }
1878
+
1879
+ mrb_int start_byte_offset = str_char_to_byte_offset(str, char_start);
1880
+ if (start_byte_offset == -1) return 0;
1881
+
1882
+ mrb_int byte_offset = start_byte_offset;
1883
+ mrb_int current_char_len = 0;
1884
+ while (byte_offset < str_byte_len && current_char_len < char_len) {
1885
+ mrb_int cl = mrb_utf8len(p + byte_offset, p + str_byte_len - byte_offset);
1886
+ if (cl == 0) break;
1887
+ byte_offset += cl;
1888
+ current_char_len++;
1889
+ }
1890
+
1891
+ return byte_offset - start_byte_offset;
1892
+ }
1893
+ #endif
1894
+
1895
+ static mrb_value
1896
+ mrb_str_slice_bang(mrb_state *mrb, mrb_value self)
1897
+ {
1898
+ mrb_check_frozen(mrb, mrb_obj_ptr(self));
1899
+
1900
+ mrb_value arg1, arg2;
1901
+ mrb_int argc = mrb_get_args(mrb, "o|o", &arg1, &arg2);
1902
+
1903
+ struct RString *str = mrb_str_ptr(self);
1904
+ const char *ptr = RSTRING_PTR(self);
1905
+
1906
+ #ifdef MRB_UTF8_STRING
1907
+ mrb_int str_len = str_char_count(self);
1908
+ #else
1909
+ mrb_int str_len = RSTRING_LEN(self);
1910
+ #endif
1911
+
1912
+ mrb_int beg, len;
1913
+
1914
+ if (argc == 1) {
1915
+ if (mrb_string_p(arg1)) {
1916
+ mrb_int pos = mrb_str_index(mrb, self, RSTRING_PTR(arg1), RSTRING_LEN(arg1), 0);
1917
+ if (pos == -1) return mrb_nil_value();
1918
+ #ifdef MRB_UTF8_STRING
1919
+ beg = str_char_count(mrb_str_substr(mrb, self, 0, pos));
1920
+ len = str_char_count(arg1);
1921
+ #else
1922
+ beg = pos;
1923
+ len = RSTRING_LEN(arg1);
1924
+ #endif
1925
+ }
1926
+ else if (mrb_range_p(arg1)) {
1927
+ if (mrb_range_beg_len(mrb, arg1, &beg, &len, str_len, TRUE) != MRB_RANGE_OK) {
1928
+ return mrb_nil_value();
1929
+ }
1930
+ }
1931
+ else {
1932
+ beg = mrb_as_int(mrb, arg1);
1933
+ if (beg < 0) beg += str_len;
1934
+ if (beg < 0 || beg >= str_len) return mrb_nil_value();
1935
+ len = 1;
1936
+ }
1937
+ }
1938
+ else { // argc == 2
1939
+ beg = mrb_as_int(mrb, arg1);
1940
+ len = mrb_as_int(mrb, arg2);
1941
+ if (beg < 0) beg += str_len;
1942
+ if (len < 0) return mrb_nil_value();
1943
+ if (beg < 0 || beg > str_len) return mrb_nil_value();
1944
+ }
1945
+
1946
+ if (beg > str_len) return mrb_nil_value();
1947
+ if (beg + len > str_len) {
1948
+ len = str_len - beg;
1949
+ }
1950
+ if (len < 0) len = 0;
1951
+
1952
+ #ifdef MRB_UTF8_STRING
1953
+ mrb_int byte_beg = str_char_to_byte_offset(self, beg);
1954
+ mrb_int byte_len = str_chars_to_byte_len(self, beg, len);
1955
+ #else
1956
+ mrb_int byte_beg = beg;
1957
+ mrb_int byte_len = len;
1958
+ #endif
1959
+
1960
+ if (byte_beg < 0 || byte_beg > RSTRING_LEN(self) || byte_beg + byte_len > RSTRING_LEN(self)) {
1961
+ return mrb_nil_value();
1962
+ }
1963
+
1964
+ mrb_value result = mrb_str_new(mrb, RSTRING_PTR(self) + byte_beg, byte_len);
1965
+
1966
+ mrb_str_modify(mrb, str);
1967
+ ptr = RSTRING_PTR(self);
1968
+ memmove((char*)ptr + byte_beg, ptr + byte_beg + byte_len, RSTRING_LEN(self) - byte_beg - byte_len);
1969
+ RSTR_SET_LEN(str, RSTRING_LEN(self) - byte_len);
1970
+
1971
+ return result;
1972
+ }
1973
+
1974
+ /*
1975
+ * call-seq:
1976
+ * string.clear -> string
1977
+ *
1978
+ * Makes string empty.
1979
+ *
1980
+ * a = "abcde"
1981
+ * a.clear #=> ""
1982
+ */
1983
+ static mrb_value
1984
+ str_clear(mrb_state *mrb, mrb_value self)
1985
+ {
1986
+ struct RString *s = mrb_str_ptr(self);
1987
+ mrb_str_modify(mrb, s);
1988
+ RSTR_SET_LEN(s, 0);
1989
+ return self;
1990
+ }
1991
+
1992
+ /*
1993
+ * call-seq:
1994
+ * str.partition(sep) -> [head, sep, tail]
1995
+ *
1996
+ * Searches for the first occurrence of `sep` in `str`. If `sep` is found,
1997
+ * returns a 3-element array containing the part of `str` before `sep`,
1998
+ * `sep` itself, and the part of `str` after `sep`.
1999
+ *
2000
+ * If `sep` is not found, returns a 3-element array containing `str`,
2001
+ * an empty string, and an empty string.
2002
+ *
2003
+ * "hello world".partition(" ") #=> ["hello", " ", "world"]
2004
+ * "hello world".partition("o") #=> ["hell", "o", " world"]
2005
+ * "hello world".partition("x") #=> ["hello world", "", ""]
2006
+ */
2007
+ static mrb_value
2008
+ str_partition(mrb_state *mrb, mrb_value self)
2009
+ {
2010
+ mrb_value sep;
2011
+ mrb_get_args(mrb, "S", &sep);
2012
+
2013
+ mrb_int self_len = RSTRING_LEN(self);
2014
+ mrb_int sep_len = RSTRING_LEN(sep);
2015
+ const char *self_ptr = RSTRING_PTR(self);
2016
+ const char *sep_ptr = RSTRING_PTR(sep);
2017
+
2018
+ mrb_value result_ary = mrb_ary_new_capa(mrb, 3);
2019
+
2020
+ if (sep_len == 0) {
2021
+ mrb_ary_push(mrb, result_ary, mrb_str_new_lit(mrb, ""));
2022
+ mrb_ary_push(mrb, result_ary, mrb_str_new_lit(mrb, ""));
2023
+ mrb_ary_push(mrb, result_ary, mrb_str_dup(mrb, self));
2024
+ return result_ary;
2025
+ }
2026
+
2027
+ const char *found_ptr = NULL;
2028
+ for (mrb_int i = 0; i <= self_len - sep_len; ++i) {
2029
+ if (memcmp(self_ptr + i, sep_ptr, sep_len) == 0) {
2030
+ found_ptr = self_ptr + i;
2031
+ break;
2032
+ }
2033
+ }
2034
+
2035
+ if (found_ptr) {
2036
+ mrb_int pre_len = found_ptr - self_ptr;
2037
+ mrb_int post_len = self_len - pre_len - sep_len;
2038
+
2039
+ mrb_ary_push(mrb, result_ary, mrb_str_new(mrb, self_ptr, pre_len));
2040
+ mrb_ary_push(mrb, result_ary, mrb_str_dup(mrb, sep));
2041
+ mrb_ary_push(mrb, result_ary, mrb_str_new(mrb, found_ptr + sep_len, post_len));
2042
+ }
2043
+ else {
2044
+ mrb_ary_push(mrb, result_ary, mrb_str_dup(mrb, self));
2045
+ mrb_ary_push(mrb, result_ary, mrb_str_new_lit(mrb, ""));
2046
+ mrb_ary_push(mrb, result_ary, mrb_str_new_lit(mrb, ""));
2047
+ }
2048
+
2049
+ return result_ary;
2050
+ }
2051
+
2052
+ /*
2053
+ * call-seq:
2054
+ * str.rpartition(sep) -> [head, sep, tail]
2055
+ *
2056
+ * Searches for the last occurrence of `sep` in `str`. If `sep` is found,
2057
+ * returns a 3-element array containing the part of `str` before `sep`,
2058
+ * `sep` itself, and the part of `str` after `sep`.
2059
+ *
2060
+ * If `sep` is not found, returns a 3-element array containing an empty string,
2061
+ * an empty string, and `str`.
2062
+ *
2063
+ * "hello world".rpartition(" ") #=> ["hello", " ", "world"]
2064
+ * "hello world".rpartition("o") #=> ["hello w", "o", "rld"]
2065
+ * "hello world".rpartition("x") #=> ["", "", "hello world"]
2066
+ */
2067
+ static mrb_value
2068
+ str_rpartition(mrb_state *mrb, mrb_value self)
2069
+ {
2070
+ mrb_value sep;
2071
+ mrb_get_args(mrb, "S", &sep);
2072
+
2073
+ mrb_int self_len = RSTRING_LEN(self);
2074
+ mrb_int sep_len = RSTRING_LEN(sep);
2075
+ const char *self_ptr = RSTRING_PTR(self);
2076
+ const char *sep_ptr = RSTRING_PTR(sep);
2077
+
2078
+ mrb_value result_ary = mrb_ary_new_capa(mrb, 3);
2079
+
2080
+ if (sep_len == 0) {
2081
+ mrb_ary_push(mrb, result_ary, mrb_str_dup(mrb, self));
2082
+ mrb_ary_push(mrb, result_ary, mrb_str_new_lit(mrb, ""));
2083
+ mrb_ary_push(mrb, result_ary, mrb_str_new_lit(mrb, ""));
2084
+ return result_ary;
2085
+ }
2086
+
2087
+ const char *found_ptr = NULL;
2088
+ for (mrb_int i = self_len - sep_len; i >= 0; --i) {
2089
+ if (memcmp(self_ptr + i, sep_ptr, sep_len) == 0) {
2090
+ found_ptr = self_ptr + i;
2091
+ break;
2092
+ }
2093
+ }
2094
+
2095
+ if (found_ptr) {
2096
+ mrb_int pre_len = found_ptr - self_ptr;
2097
+ mrb_int post_len = self_len - pre_len - sep_len;
2098
+
2099
+ mrb_ary_push(mrb, result_ary, mrb_str_new(mrb, self_ptr, pre_len));
2100
+ mrb_ary_push(mrb, result_ary, mrb_str_dup(mrb, sep));
2101
+ mrb_ary_push(mrb, result_ary, mrb_str_new(mrb, found_ptr + sep_len, post_len));
2102
+ }
2103
+ else {
2104
+ mrb_ary_push(mrb, result_ary, mrb_str_new_lit(mrb, ""));
2105
+ mrb_ary_push(mrb, result_ary, mrb_str_new_lit(mrb, ""));
2106
+ mrb_ary_push(mrb, result_ary, mrb_str_dup(mrb, self));
2107
+ }
2108
+
2109
+ return result_ary;
2110
+ }
2111
+
2112
+ /*
2113
+ * call-seq:
2114
+ * str.insert(index, other_str) -> str
2115
+ *
2116
+ * Inserts *other_str* before the character at the given
2117
+ * *index*, modifying *str*. Negative indices count from the
2118
+ * end of the string, and insert <em>after</em> the given character.
2119
+ * The intent is insert *aString* so that it starts at the given
2120
+ * *index*.
2121
+ *
2122
+ * "abcd".insert(0, 'X') #=> "Xabcd"
2123
+ * "abcd".insert(3, 'X') #=> "abcXd"
2124
+ * "abcd".insert(4, 'X') #=> "abcdX"
2125
+ * "abcd".insert(-3, 'X') #=> "abXcd"
2126
+ * "abcd".insert(-1, 'X') #=> "abcdX"
2127
+ */
2128
+ static mrb_value
2129
+ str_insert(mrb_state *mrb, mrb_value self)
2130
+ {
2131
+ mrb_int idx;
2132
+ mrb_value str_to_insert;
2133
+ mrb_get_args(mrb, "iS", &idx, &str_to_insert);
2134
+
2135
+ struct RString *s = mrb_str_ptr(self);
2136
+ mrb_int self_len = RSTR_LEN(s);
2137
+ mrb_int insert_len = RSTRING_LEN(str_to_insert);
2138
+
2139
+ mrb_check_frozen(mrb, s);
2140
+
2141
+ if (idx < 0) {
2142
+ idx = self_len + idx + 1;
2143
+ }
2144
+
2145
+ if (idx < 0 || idx > self_len) {
2146
+ mrb_raisef(mrb, E_INDEX_ERROR, "index %S out of string", mrb_int_value(mrb, idx));
2147
+ }
2148
+
2149
+ mrb_str_modify(mrb, s);
2150
+ mrb_str_resize(mrb, self, self_len + insert_len);
2151
+
2152
+ char *p = RSTRING_PTR(self);
2153
+ memmove(p + idx + insert_len, p + idx, self_len - idx);
2154
+ memcpy(p + idx, RSTRING_PTR(str_to_insert), insert_len);
2155
+
2156
+ return self;
2157
+ }
2158
+
2159
+ /*
2160
+ * call-seq:
2161
+ * str.prepend(*other_str) -> str
2162
+ *
2163
+ * Prepend---Prepend the given strings to *str*.
2164
+ *
2165
+ * a = "world"
2166
+ * a.prepend("hello ") #=> "hello world"
2167
+ * a #=> "hello world"
2168
+ *
2169
+ * Multiple arguments are prepended in order:
2170
+ *
2171
+ * a = "world"
2172
+ * a.prepend("hello ", "beautiful ") #=> "hello beautiful world"
2173
+ */
2174
+ static mrb_value
2175
+ str_prepend(mrb_state *mrb, mrb_value self)
2176
+ {
2177
+ mrb_value *argv;
2178
+ mrb_int argc;
2179
+ mrb_get_args(mrb, "*", &argv, &argc);
2180
+
2181
+ if (argc == 0) {
2182
+ return self;
2183
+ }
2184
+
2185
+ struct RString *s = mrb_str_ptr(self);
2186
+ mrb_check_frozen(mrb, s);
2187
+
2188
+ /* Calculate total length needed for all prepended strings */
2189
+ mrb_int total_prepend_len = 0;
2190
+ for (mrb_int i = 0; i < argc; i++) {
2191
+ mrb_ensure_string_type(mrb, argv[i]);
2192
+ total_prepend_len += RSTRING_LEN(argv[i]);
2193
+ }
2194
+
2195
+ if (total_prepend_len == 0) {
2196
+ return self;
2197
+ }
2198
+
2199
+ mrb_int self_len = RSTRING_LEN(self);
2200
+ mrb_str_modify(mrb, s);
2201
+ mrb_str_resize(mrb, self, self_len + total_prepend_len);
2202
+
2203
+ char *p = RSTRING_PTR(self);
2204
+
2205
+ /* Move original content to the end */
2206
+ memmove(p + total_prepend_len, p, self_len);
2207
+
2208
+ /* Copy prepended strings in order */
2209
+ mrb_int offset = 0;
2210
+ for (mrb_int i = 0; i < argc; i++) {
2211
+ mrb_int arg_len = RSTRING_LEN(argv[i]);
2212
+ if (arg_len > 0) {
2213
+ memcpy(p + offset, RSTRING_PTR(argv[i]), arg_len);
2214
+ offset += arg_len;
2215
+ }
2216
+ }
2217
+
2218
+ return self;
2219
+ }
2220
+
2221
+ /* ---------------------------*/
2222
+ static const mrb_mt_entry string_ext_rom_entries[] = {
2223
+ MRB_MT_ENTRY(mrb_str_dump, MRB_SYM(dump), MRB_ARGS_NONE()),
2224
+ MRB_MT_ENTRY(str_swapcase_bang, MRB_SYM_B(swapcase), MRB_ARGS_NONE()),
2225
+ MRB_MT_ENTRY(mrb_str_slice_bang, MRB_SYM_B(slice), MRB_ARGS_ARG(1,1)),
2226
+ MRB_MT_ENTRY(str_swapcase, MRB_SYM(swapcase), MRB_ARGS_NONE()),
2227
+ MRB_MT_ENTRY(str_clear, MRB_SYM(clear), MRB_ARGS_NONE()),
2228
+ MRB_MT_ENTRY(str_concat_m, MRB_OPSYM(lshift), MRB_ARGS_REQ(1)),
2229
+ MRB_MT_ENTRY(str_concat_m, MRB_SYM(concat), MRB_ARGS_REQ(1)),
2230
+ MRB_MT_ENTRY(str_append_as_bytes, MRB_SYM(append_as_bytes), MRB_ARGS_REQ(1)),
2231
+ MRB_MT_ENTRY(str_count, MRB_SYM(count), MRB_ARGS_REQ(1)),
2232
+ MRB_MT_ENTRY(str_tr_m, MRB_SYM(tr), MRB_ARGS_REQ(2)),
2233
+ MRB_MT_ENTRY(str_partition, MRB_SYM(partition), MRB_ARGS_REQ(1)),
2234
+ MRB_MT_ENTRY(str_rpartition, MRB_SYM(rpartition), MRB_ARGS_REQ(1)),
2235
+ MRB_MT_ENTRY(str_insert, MRB_SYM(insert), MRB_ARGS_REQ(2)),
2236
+ MRB_MT_ENTRY(str_prepend, MRB_SYM(prepend), MRB_ARGS_REST()),
2237
+ MRB_MT_ENTRY(str_tr_bang, MRB_SYM_B(tr), MRB_ARGS_REQ(2)),
2238
+ MRB_MT_ENTRY(str_tr_s, MRB_SYM(tr_s), MRB_ARGS_REQ(2)),
2239
+ MRB_MT_ENTRY(str_tr_s_bang, MRB_SYM_B(tr_s), MRB_ARGS_REQ(2)),
2240
+ MRB_MT_ENTRY(str_squeeze_m, MRB_SYM(squeeze), MRB_ARGS_OPT(1)),
2241
+ MRB_MT_ENTRY(str_squeeze_bang, MRB_SYM_B(squeeze), MRB_ARGS_OPT(1)),
2242
+ MRB_MT_ENTRY(str_delete_m, MRB_SYM(delete), MRB_ARGS_REQ(1)),
2243
+ MRB_MT_ENTRY(str_delete_bang, MRB_SYM_B(delete), MRB_ARGS_REQ(1)),
2244
+ MRB_MT_ENTRY(str_start_with, MRB_SYM_Q(start_with), MRB_ARGS_REST()),
2245
+ MRB_MT_ENTRY(str_end_with, MRB_SYM_Q(end_with), MRB_ARGS_REST()),
2246
+ MRB_MT_ENTRY(str_hex, MRB_SYM(hex), MRB_ARGS_NONE()),
2247
+ MRB_MT_ENTRY(str_oct, MRB_SYM(oct), MRB_ARGS_NONE()),
2248
+ MRB_MT_ENTRY(str_chr, MRB_SYM(chr), MRB_ARGS_NONE()),
2249
+ MRB_MT_ENTRY(str_succ, MRB_SYM(succ), MRB_ARGS_NONE()),
2250
+ MRB_MT_ENTRY(str_succ_bang, MRB_SYM_B(succ), MRB_ARGS_NONE()),
2251
+ MRB_MT_ENTRY(str_succ, MRB_SYM(next), MRB_ARGS_NONE()),
2252
+ MRB_MT_ENTRY(str_succ_bang, MRB_SYM_B(next), MRB_ARGS_NONE()),
2253
+ MRB_MT_ENTRY(str_ord, MRB_SYM(ord), MRB_ARGS_NONE()),
2254
+ MRB_MT_ENTRY(str_del_prefix_bang, MRB_SYM_B(delete_prefix), MRB_ARGS_REQ(1)),
2255
+ MRB_MT_ENTRY(str_del_prefix, MRB_SYM(delete_prefix), MRB_ARGS_REQ(1)),
2256
+ MRB_MT_ENTRY(str_del_suffix_bang, MRB_SYM_B(delete_suffix), MRB_ARGS_REQ(1)),
2257
+ MRB_MT_ENTRY(str_del_suffix, MRB_SYM(delete_suffix), MRB_ARGS_REQ(1)),
2258
+ MRB_MT_ENTRY(str_casecmp, MRB_SYM(casecmp), MRB_ARGS_REQ(1)),
2259
+ MRB_MT_ENTRY(str_casecmp_p, MRB_SYM_Q(casecmp), MRB_ARGS_REQ(1)),
2260
+ MRB_MT_ENTRY(str_uplus, MRB_OPSYM(plus), MRB_ARGS_NONE()),
2261
+ MRB_MT_ENTRY(str_uminus, MRB_OPSYM(minus), MRB_ARGS_NONE()),
2262
+ MRB_MT_ENTRY(str_ascii_only_p, MRB_SYM_Q(ascii_only), MRB_ARGS_NONE()),
2263
+ MRB_MT_ENTRY(str_b, MRB_SYM(b), MRB_ARGS_NONE()),
2264
+ MRB_MT_ENTRY(str_lines, MRB_SYM(__lines), MRB_ARGS_NONE()),
2265
+ MRB_MT_ENTRY(str_codepoints, MRB_SYM(__codepoints), MRB_ARGS_NONE()),
2266
+ MRB_MT_ENTRY(str_lstrip, MRB_SYM(lstrip), MRB_ARGS_NONE()),
2267
+ MRB_MT_ENTRY(str_rstrip, MRB_SYM(rstrip), MRB_ARGS_NONE()),
2268
+ MRB_MT_ENTRY(str_strip, MRB_SYM(strip), MRB_ARGS_NONE()),
2269
+ MRB_MT_ENTRY(str_lstrip_bang, MRB_SYM_B(lstrip), MRB_ARGS_NONE()),
2270
+ MRB_MT_ENTRY(str_rstrip_bang, MRB_SYM_B(rstrip), MRB_ARGS_NONE()),
2271
+ MRB_MT_ENTRY(str_strip_bang, MRB_SYM_B(strip), MRB_ARGS_NONE()),
2272
+ MRB_MT_ENTRY(str_chars_ary, MRB_SYM(__chars), MRB_ARGS_NONE()),
2273
+ MRB_MT_ENTRY(str_ljust_core, MRB_SYM(ljust), MRB_ARGS_ARG(1,1)),
2274
+ MRB_MT_ENTRY(str_rjust_core, MRB_SYM(rjust), MRB_ARGS_ARG(1,1)),
2275
+ MRB_MT_ENTRY(str_center_core, MRB_SYM(center), MRB_ARGS_ARG(1,1)),
2276
+ };
2277
+
2278
+ void
2279
+ mrb_mruby_string_ext_gem_init(mrb_state* mrb)
2280
+ {
2281
+ struct RClass *s = mrb->string_class;
2282
+
2283
+ MRB_MT_INIT_ROM(mrb, s, string_ext_rom_entries);
2284
+ mrb_define_method_id(mrb, mrb->integer_class, MRB_SYM(chr), int_chr, MRB_ARGS_NONE()|MRB_ARGS_OPT(1));
2285
+ }
2286
+
2287
+ void
2288
+ mrb_mruby_string_ext_gem_final(mrb_state* mrb)
2289
+ {
2290
+ }