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,1739 @@
1
+ /*
2
+ ** time.c - Time class
3
+ **
4
+ ** See Copyright Notice in mruby.h
5
+ */
6
+
7
+ #include <mruby.h>
8
+ #include <mruby/class.h>
9
+ #include <mruby/data.h>
10
+ #include <mruby/numeric.h>
11
+ #include <mruby/time.h>
12
+ #include <mruby/string.h>
13
+ #include <mruby/internal.h>
14
+ #include <mruby/presym.h>
15
+
16
+ #ifdef MRB_NO_STDIO
17
+ #include <string.h>
18
+ #endif
19
+
20
+
21
+ #include <stdlib.h>
22
+ #ifndef _WIN32
23
+ #include <unistd.h>
24
+ #endif
25
+
26
+ #define NDIV(x,y) (-(-((x)+1)/(y))-1)
27
+ #define TO_S_FMT "%Y-%m-%d %H:%M:%S "
28
+
29
+ /* Time unit constants */
30
+ #define USECS_PER_SEC 1000000L
31
+ #define USECS_PER_SEC_F 1.0e6
32
+ #define NSECS_PER_USEC 1000L
33
+ #define SECS_PER_MIN 60
34
+ #define MINS_PER_HOUR 60
35
+ #define HOURS_PER_DAY 24
36
+ #define DAYS_PER_YEAR 365
37
+ #define DAYS_PER_LEAP_YEAR 366
38
+ #define MONTHS_PER_YEAR 12
39
+
40
+ /* Calendar calculation constants */
41
+ #define TM_YEAR_BASE 1900
42
+ #define EPOCH_YEAR_OFFSET 70
43
+ #define LEAP_YEAR_DIVISOR 4
44
+ #define LEAP_YEAR_NON_DIVISOR_CENTURY 100
45
+ #define LEAP_YEAR_DIVISOR_QUAD_CENTURY 400
46
+
47
+ /* Windows specific time constants */
48
+ #define WINDOWS_EPOCH_BIAS_USEC UI64(116444736000000000) /* Unix epoch bias in 100ns intervals for Windows FILETIME */
49
+ #define HUNDRED_NS_PER_USEC 10 /* Number of 100-nanosecond intervals in a microsecond */
50
+
51
+ #if defined(_MSC_VER) && _MSC_VER < 1800
52
+ double round(double x) {
53
+ return floor(x + 0.5);
54
+ }
55
+ #endif
56
+
57
+ #ifndef MRB_NO_FLOAT
58
+ # if !defined(__MINGW64__) && defined(_WIN32)
59
+ # define llround(x) round(x)
60
+ # endif
61
+ #endif
62
+
63
+ #if defined(__MINGW64__) || defined(__MINGW32__)
64
+ # include <sys/time.h>
65
+ #endif
66
+
67
+ /** Time class configuration */
68
+
69
+ /* Platform detection for Windows variants */
70
+ #if defined(_MSC_VER) && _MSC_VER < 1900 || defined(__MINGW64__) || defined(__MINGW32__)
71
+ #define MRB_TIME_WINDOWS_NO_STRFTIME_Z
72
+ #endif
73
+
74
+ /* gettimeofday(2) */
75
+ /* C99 does not have gettimeofday that is required to retrieve microseconds */
76
+ /* uncomment following macro on platforms without gettimeofday(2) */
77
+ /* #define NO_GETTIMEOFDAY */
78
+
79
+ /* gmtime(3) */
80
+ /* C99 does not have reentrant gmtime_r() so it might cause troubles under */
81
+ /* multi-threading environment. undef following macro on platforms that */
82
+ /* does not have gmtime_r() and localtime_r(). */
83
+ /* #define NO_GMTIME_R */
84
+
85
+ #ifdef _WIN32
86
+ #ifdef _MSC_VER
87
+ /* Win32 platform do not provide gmtime_r/localtime_r; emulate them using gmtime_s/localtime_s */
88
+ #define gmtime_r(tp, tm) ((gmtime_s((tm), (tp)) == 0) ? (tm) : NULL)
89
+ #define localtime_r(tp, tm) ((localtime_s((tm), (tp)) == 0) ? (tm) : NULL)
90
+ #else
91
+ #define NO_GMTIME_R
92
+ #endif
93
+ #endif
94
+ #ifdef __STRICT_ANSI__
95
+ /* Strict ANSI (e.g. -std=c99) do not provide gmtime_r/localtime_r */
96
+ #define NO_GMTIME_R
97
+ #endif
98
+
99
+ /* asctime(3) */
100
+ /* mruby usually use its own implementation of struct tm to string conversion */
101
+ /* except when MRB_NO_STDIO is set. In that case, it uses asctime() or asctime_r(). */
102
+ /* By default mruby tries to use asctime_r() which is reentrant. */
103
+ /* Undef following macro on platforms that does not have asctime_r(). */
104
+ /* #define NO_ASCTIME_R */
105
+
106
+ /* timegm(3) */
107
+ /* mktime() creates tm structure for localtime; timegm() is for UTC time */
108
+ /* define following macro to use probably faster timegm() on the platform */
109
+ /* #define USE_SYSTEM_TIMEGM */
110
+
111
+ /** end of Time class configuration */
112
+
113
+ /* protection against incorrectly defined _POSIX_TIMERS */
114
+ #if defined(_POSIX_TIMERS) && (_POSIX_TIMERS + 0) > 0 && defined(CLOCK_REALTIME)
115
+ # define USE_CLOCK_GETTIME
116
+ #endif
117
+
118
+ #if !defined(NO_GETTIMEOFDAY) && defined(_WIN32) && !defined(USE_CLOCK_GETTIME)
119
+ /* Windows gettimeofday polyfill */
120
+ #define WIN32_LEAN_AND_MEAN /* don't include winsock.h */
121
+ #include <windows.h>
122
+ #define gettimeofday my_gettimeofday
123
+
124
+ #ifdef _MSC_VER
125
+ # define UI64(x) x##ui64
126
+ #else
127
+ # define UI64(x) x##ull
128
+ #endif
129
+
130
+ typedef long suseconds_t;
131
+
132
+ #if (!defined __MINGW64__) && (!defined __MINGW32__)
133
+ struct timeval {
134
+ time_t tv_sec;
135
+ suseconds_t tv_usec;
136
+ };
137
+ #endif
138
+
139
+ /*
140
+ * Polyfill for gettimeofday on Windows platforms that may not have it (e.g., older MSVC).
141
+ * Retrieves the current system time as FILETIME, converts it to Unix epoch,
142
+ * and then splits it into seconds and microseconds.
143
+ * The timezone argument (tz) is not supported.
144
+ */
145
+ static int
146
+ gettimeofday(struct timeval *tv, void *tz)
147
+ {
148
+ if (tz) {
149
+ mrb_assert(0); /* timezone is not supported */
150
+ }
151
+ if (tv) {
152
+ union {
153
+ FILETIME ft;
154
+ unsigned __int64 u64;
155
+ } t;
156
+ GetSystemTimeAsFileTime(&t.ft); /* 100 ns intervals since Windows epoch */
157
+ t.u64 -= WINDOWS_EPOCH_BIAS_USEC; /* Unix epoch bias */
158
+ t.u64 /= HUNDRED_NS_PER_USEC; /* to microseconds */
159
+ tv->tv_sec = (time_t)(t.u64 / USECS_PER_SEC);
160
+ tv->tv_usec = t.u64 % USECS_PER_SEC;
161
+ }
162
+ return 0;
163
+ }
164
+
165
+ #elif !defined(NO_GETTIMEOFDAY)
166
+ /* Non-Windows platforms use standard sys/time.h */
167
+ #include <sys/time.h>
168
+ #endif
169
+ #ifdef NO_GMTIME_R
170
+ #define gmtime_r(t,r) gmtime(t)
171
+ #define localtime_r(t,r) localtime(t)
172
+ #endif
173
+
174
+ /*
175
+ * USE_SYSTEM_TIMEGM: If defined, the system's `timegm` is used.
176
+ * Otherwise, a custom implementation `my_timgm` is used.
177
+ * `timegm` converts a `struct tm` (broken-down time) in UTC to a `time_t` (seconds since epoch).
178
+ * This is the reverse of `gmtime_r`.
179
+ */
180
+ #ifndef USE_SYSTEM_TIMEGM
181
+ #define timegm my_timgm
182
+
183
+ /* Helper function to check for leap years. */
184
+ static unsigned int
185
+ is_leapyear(unsigned int y)
186
+ {
187
+ return (y % LEAP_YEAR_DIVISOR) == 0 && ((y % LEAP_YEAR_NON_DIVISOR_CENTURY) != 0 || (y % LEAP_YEAR_DIVISOR_QUAD_CENTURY) == 0);
188
+ }
189
+
190
+ static time_t
191
+ timegm(struct tm *tm)
192
+ {
193
+ static const unsigned int ndays[2][MONTHS_PER_YEAR] = {
194
+ {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, /* Non-leap year */
195
+ {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} /* Leap year */
196
+ };
197
+ time_t r = 0; /* Accumulator for seconds since epoch */
198
+ int i;
199
+ /* Get a pointer to the array of days in each month for the given year (leap or non-leap) */
200
+ unsigned int *nday = (unsigned int*) ndays[is_leapyear(tm->tm_year+TM_YEAR_BASE)];
201
+
202
+ /* Calculate seconds from years since epoch */
203
+ if (tm->tm_year >= EPOCH_YEAR_OFFSET) { /* Years from 1970 up to tm_year */
204
+ for (i = EPOCH_YEAR_OFFSET; i < tm->tm_year; ++i)
205
+ r += is_leapyear(i+TM_YEAR_BASE) ? (DAYS_PER_LEAP_YEAR*HOURS_PER_DAY*SECS_PER_MIN*MINS_PER_HOUR) : (DAYS_PER_YEAR*HOURS_PER_DAY*SECS_PER_MIN*MINS_PER_HOUR);
206
+ }
207
+ else { /* Years before 1970 down to tm_year */
208
+ for (i = tm->tm_year; i < EPOCH_YEAR_OFFSET; ++i)
209
+ r -= is_leapyear(i+TM_YEAR_BASE) ? (DAYS_PER_LEAP_YEAR*HOURS_PER_DAY*SECS_PER_MIN*MINS_PER_HOUR) : (DAYS_PER_YEAR*HOURS_PER_DAY*SECS_PER_MIN*MINS_PER_HOUR);
210
+ }
211
+ /* Add seconds from months in the current year */
212
+ for (i = 0; i < tm->tm_mon; ++i)
213
+ r += nday[i] * HOURS_PER_DAY * SECS_PER_MIN * MINS_PER_HOUR;
214
+ /* Add seconds from days in the current month */
215
+ r += (tm->tm_mday - 1) * HOURS_PER_DAY * SECS_PER_MIN * MINS_PER_HOUR;
216
+ /* Add seconds from hours, minutes, and seconds in the current day */
217
+ r += tm->tm_hour * SECS_PER_MIN * MINS_PER_HOUR;
218
+ r += tm->tm_min * SECS_PER_MIN;
219
+ r += tm->tm_sec;
220
+ return r;
221
+ }
222
+ #endif
223
+
224
+ /* Since we are limited to using ISO C99, this implementation is based
225
+ * on time_t. That means the resolution of time is only precise to the
226
+ * second level. Also, there are only 2 timezones, namely UTC and LOCAL.
227
+ */
228
+
229
+ #ifndef MRB_NO_STDIO
230
+ static const char mon_names[MONTHS_PER_YEAR][4] = {
231
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
232
+ };
233
+
234
+ static const char wday_names[7][4] = { /* Consider defining DAYS_PER_WEEK = 7 if used elsewhere */
235
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
236
+ };
237
+ #endif
238
+
239
+ struct mrb_time {
240
+ time_t sec; /* Seconds since the Epoch */
241
+ time_t nsec; /* Nanosecond fraction of the second (0-999999999) */
242
+ enum mrb_timezone timezone; /* Timezone setting (MRB_TIMEZONE_UTC or MRB_TIMEZONE_LOCAL) */
243
+ struct tm datetime; /* Cache for broken-down time based on sec, nsec, and timezone. Updated by time_update_datetime. */
244
+ };
245
+
246
+ static const struct mrb_data_type time_type = { "Time", mrb_free }; /* mrb_free is the standard C free() */
247
+
248
+ #define MRB_TIME_T_UINT (~(time_t)0 > 0)
249
+ #define MRB_TIME_MIN ( \
250
+ MRB_TIME_T_UINT ? 0 : \
251
+ (sizeof(time_t) <= 4 ? INT32_MIN : INT64_MIN) \
252
+ )
253
+ #define MRB_TIME_MAX (time_t)( \
254
+ MRB_TIME_T_UINT ? (sizeof(time_t) <= 4 ? UINT32_MAX : UINT64_MAX) : \
255
+ (sizeof(time_t) <= 4 ? INT32_MAX : INT64_MAX) \
256
+ )
257
+
258
+ /*
259
+ * Checks if a time_t value `v` can be represented as an mrb_int without overflow or precision loss.
260
+ * This is important because mruby integers (mrb_int) might be smaller than time_t on some platforms.
261
+ * - If mrb_int can fully encompass the range of time_t, it's always TRUE.
262
+ * - Otherwise, it checks if `v` falls within the representable range of mrb_int.
263
+ * - Considers if time_t is unsigned (MRB_TIME_T_UINT).
264
+ */
265
+ static mrb_bool
266
+ fixable_time_t_p(time_t v)
267
+ {
268
+ if (MRB_INT_MIN <= MRB_TIME_MIN && MRB_TIME_MAX <= MRB_INT_MAX) return TRUE;
269
+ if (v > (time_t)MRB_INT_MAX) return FALSE;
270
+ if (MRB_TIME_T_UINT) return TRUE;
271
+ if (MRB_INT_MIN > (mrb_int)v) return FALSE;
272
+ return TRUE;
273
+ }
274
+
275
+ static void
276
+ time_out_of_range(mrb_state *mrb, mrb_value obj)
277
+ {
278
+ mrb_raisef(mrb, E_RANGE_ERROR, "%v out of Time range", obj);
279
+ }
280
+
281
+ static mrb_noreturn void
282
+ time_uninitialized(mrb_state *mrb)
283
+ {
284
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized Time");
285
+ }
286
+
287
+
288
+ #ifndef MRB_NO_FLOAT
289
+ static time_t
290
+ mrb_time_t_from_float(mrb_state *mrb, mrb_value obj, time_t *usec)
291
+ {
292
+ time_t t;
293
+ mrb_float f = mrb_float(obj);
294
+
295
+ mrb_check_num_exact(mrb, f);
296
+ if (f >= ((mrb_float)MRB_TIME_MAX-1.0) || f < ((mrb_float)MRB_TIME_MIN+1.0)) {
297
+ time_out_of_range(mrb, obj);
298
+ }
299
+
300
+ if (usec) {
301
+ double tt = floor(f);
302
+ if (!isfinite(tt)) time_out_of_range(mrb, obj);
303
+ t = (time_t)tt;
304
+ *usec = (time_t)trunc((f - tt) * USECS_PER_SEC_F);
305
+ }
306
+ else {
307
+ double tt = round(f);
308
+ if (!isfinite(tt)) time_out_of_range(mrb, obj);
309
+ t = (time_t)tt;
310
+ }
311
+ return t;
312
+ }
313
+ #endif /* MRB_NO_FLOAT */
314
+
315
+ static time_t
316
+ mrb_time_t_from_integer(mrb_state *mrb, mrb_value obj, time_t *usec)
317
+ {
318
+ time_t t;
319
+ mrb_int i = mrb_integer(obj);
320
+
321
+ if ((MRB_INT_MAX > MRB_TIME_MAX && i > 0 && (time_t)i > MRB_TIME_MAX) ||
322
+ (0 > MRB_TIME_MIN && MRB_TIME_MIN > MRB_INT_MIN && MRB_TIME_MIN > i)) {
323
+ time_out_of_range(mrb, obj);
324
+ }
325
+
326
+ t = (time_t)i;
327
+ if (usec) { *usec = 0; }
328
+ return t;
329
+ }
330
+
331
+ #ifdef MRB_USE_BIGINT
332
+ static time_t
333
+ mrb_time_t_from_bigint(mrb_state *mrb, mrb_value obj, time_t *usec)
334
+ {
335
+ time_t t;
336
+ if (sizeof(time_t) > sizeof(mrb_int)) {
337
+ if (MRB_TIME_T_UINT) {
338
+ t = (time_t)mrb_bint_as_uint64(mrb, obj);
339
+ }
340
+ else {
341
+ t = (time_t)mrb_bint_as_int64(mrb, obj);
342
+ }
343
+ if (usec) { *usec = 0; }
344
+ }
345
+ else {
346
+ mrb_int i = mrb_bint_as_int(mrb, obj);
347
+ obj = mrb_int_value(mrb, i);
348
+ /* Call the integer handler for the converted value */
349
+ t = mrb_time_t_from_integer(mrb, obj, usec);
350
+ }
351
+ return t;
352
+ }
353
+ #endif /* MRB_USE_BIGINT */
354
+
355
+ static time_t
356
+ mrb_to_time_t(mrb_state *mrb, mrb_value obj, time_t *usec)
357
+ {
358
+ switch (mrb_type(obj)) {
359
+ #ifndef MRB_NO_FLOAT
360
+ case MRB_TT_FLOAT:
361
+ return mrb_time_t_from_float(mrb, obj, usec);
362
+ #endif /* MRB_NO_FLOAT */
363
+
364
+ #ifdef MRB_USE_BIGINT
365
+ case MRB_TT_BIGINT:
366
+ return mrb_time_t_from_bigint(mrb, obj, usec);
367
+ #endif /* MRB_USE_BIGINT */
368
+
369
+ case MRB_TT_INTEGER:
370
+ return mrb_time_t_from_integer(mrb, obj, usec);
371
+
372
+ default:
373
+ mrb_raisef(mrb, E_TYPE_ERROR, "cannot convert %Y to time", obj);
374
+ return 0; /* Should not reach here */
375
+ }
376
+ }
377
+
378
+ /*
379
+ * Converts a time_t value `t` into an appropriate mruby numeric value.
380
+ * - If `t` fits in mrb_int (checked by fixable_time_t_p), returns an mrb_int_value.
381
+ * - Otherwise, if MRB_USE_BIGINT is defined, returns a BigInt.
382
+ * - Otherwise, if MRB_NO_FLOAT is not defined, returns a Float.
383
+ * - Otherwise, raises an ArgumentError if the time value is too large to represent.
384
+ */
385
+ static mrb_value
386
+ time_value_from_time_t(mrb_state *mrb, time_t t)
387
+ {
388
+ if (!fixable_time_t_p(t)) {
389
+ #if defined(MRB_USE_BIGINT)
390
+ if (MRB_TIME_T_UINT) {
391
+ return mrb_bint_new_uint64(mrb, (uint64_t)t);
392
+ }
393
+ else {
394
+ return mrb_bint_new_int64(mrb, (int64_t)t);
395
+ }
396
+ #elif !defined(MRB_NO_FLOAT)
397
+ return mrb_float_value(mrb, (mrb_float)t);
398
+ #else
399
+ mrb_raise(mrb, E_RANGE_ERROR, "Time out of range");
400
+ #endif
401
+ }
402
+ return mrb_int_value(mrb, (mrb_int)t);
403
+ }
404
+
405
+ /** Updates the datetime of a mrb_time based on it's timezone and
406
+ seconds setting. Returns self on success, NULL of failure.
407
+ if `dealloc` is set `true`, it frees `self` on error. */
408
+ static struct mrb_time*
409
+ time_update_datetime(mrb_state *mrb, struct mrb_time *self, int dealloc)
410
+ {
411
+ time_t t = self->sec;
412
+ struct tm *aid;
413
+
414
+ if (self->timezone == MRB_TIMEZONE_UTC) {
415
+ aid = gmtime_r(&t, &self->datetime);
416
+ }
417
+ else {
418
+ aid = localtime_r(&t, &self->datetime);
419
+ }
420
+ if (!aid) {
421
+ if (dealloc) mrb_free(mrb, self);
422
+ time_out_of_range(mrb, time_value_from_time_t(mrb, t));
423
+ /* not reached */
424
+ return NULL;
425
+ }
426
+ #ifdef NO_GMTIME_R
427
+ /*
428
+ * If reentrant gmtime_r/localtime_r are not available (NO_GMTIME_R is defined),
429
+ * standard gmtime/localtime are used. These functions often return a pointer
430
+ * to a static internal buffer. To avoid this buffer being overwritten by subsequent
431
+ * calls, the data pointed to by `aid` must be copied into `self->datetime`.
432
+ */
433
+ self->datetime = *aid; /* copy data from static buffer */
434
+ #endif
435
+
436
+ return self;
437
+ }
438
+
439
+ static mrb_value
440
+ time_wrap(mrb_state *mrb, struct RClass *tc, struct mrb_time *tm)
441
+ {
442
+ return mrb_obj_value(Data_Wrap_Struct(mrb, tc, &time_type, tm));
443
+ }
444
+
445
+ /* Allocates a mrb_time object and initializes it. */
446
+ static struct mrb_time*
447
+ time_alloc_time(mrb_state *mrb, time_t sec, time_t nsec, enum mrb_timezone timezone)
448
+ {
449
+ struct mrb_time *time_obj = (struct mrb_time*)mrb_malloc(mrb, sizeof(struct mrb_time));
450
+ time_obj->sec = sec;
451
+ time_obj->nsec = nsec;
452
+
453
+ /* Normalize seconds and nanoseconds. */
454
+ /* This is only necessary if time_t is signed and nsec is negative. */
455
+ if (!MRB_TIME_T_UINT && time_obj->nsec < 0) {
456
+ /*
457
+ * If nsec is negative, adjust seconds downwards.
458
+ * NDIV calculates division rounded towards negative infinity.
459
+ * For example, NDIV(-1, 1000000000) is -1, so 1 second is subtracted.
460
+ */
461
+ long sec_adjustment = (long)NDIV(time_obj->nsec, 1000000000L);
462
+ time_obj->nsec -= sec_adjustment * 1000000000L; /* Becomes positive or zero */
463
+ time_obj->sec += sec_adjustment;
464
+ }
465
+ /* Handle positive nanosecond overflow. */
466
+ else if (time_obj->nsec >= 1000000000L) {
467
+ /* If nsec is 1000000000 or more, adjust seconds upwards. */
468
+ long sec_adjustment = (long)(time_obj->nsec / 1000000000L);
469
+ time_obj->nsec -= sec_adjustment * 1000000000L; /* Reduce to < 1000000000 */
470
+ time_obj->sec += sec_adjustment;
471
+ }
472
+ time_obj->timezone = timezone;
473
+ /* Update the datetime struct; this also handles potential deallocation on error. */
474
+ time_update_datetime(mrb, time_obj, TRUE);
475
+
476
+ return time_obj;
477
+ }
478
+
479
+ /*
480
+ * Allocates and initializes an mrb_time structure from mruby values for seconds and microseconds.
481
+ * It first converts the mruby values to time_t using mrb_to_time_t,
482
+ * then calls time_alloc_time to perform the actual allocation and normalization.
483
+ */
484
+ static struct mrb_time*
485
+ time_alloc(mrb_state *mrb, mrb_value sec, mrb_value usec, enum mrb_timezone timezone)
486
+ {
487
+ time_t tsec, tusec; /* Variables to hold converted seconds and microseconds */
488
+ time_t nsec;
489
+
490
+ tsec = mrb_to_time_t(mrb, sec, &tusec);
491
+ tusec += mrb_to_time_t(mrb, usec, NULL);
492
+
493
+ /* Normalize microseconds to avoid overflow when converting to nanoseconds */
494
+ if (tusec >= USECS_PER_SEC || tusec <= -USECS_PER_SEC) {
495
+ time_t sec_adjustment = tusec / USECS_PER_SEC;
496
+ tusec -= sec_adjustment * USECS_PER_SEC;
497
+ tsec += sec_adjustment;
498
+ }
499
+
500
+ nsec = tusec * NSECS_PER_USEC;
501
+ return time_alloc_time(mrb, tsec, nsec, timezone);
502
+ }
503
+
504
+ /*
505
+ * Creates a new Time object from C-native time_t seconds and microseconds.
506
+ * This is a lower-level constructor compared to time_make.
507
+ */
508
+ static mrb_value
509
+ time_make_time(mrb_state *mrb, struct RClass *c, time_t sec, time_t usec, enum mrb_timezone timezone)
510
+ {
511
+ return time_wrap(mrb, c, time_alloc_time(mrb, sec, usec, timezone));
512
+ }
513
+
514
+ /*
515
+ * Creates a new Time object from mruby values representing seconds and microseconds.
516
+ * This is a higher-level constructor that handles mruby type conversions.
517
+ */
518
+ static mrb_value
519
+ time_make(mrb_state *mrb, struct RClass *c, mrb_value sec, mrb_value usec, enum mrb_timezone timezone)
520
+ {
521
+ return time_wrap(mrb, c, time_alloc(mrb, sec, usec, timezone));
522
+ }
523
+
524
+ /*
525
+ * Retrieves the current system time and creates a new mrb_time object.
526
+ * It uses different strategies based on platform capabilities:
527
+ * 1. timespec_get (C11 standard, if TIME_UTC is defined)
528
+ * 2. clock_gettime (POSIX standard, if USE_CLOCK_GETTIME is defined)
529
+ * 3. gettimeofday (Commonly available POSIX function, or our polyfill on Windows)
530
+ * 4. time(NULL) (Standard C, second precision only; microseconds are faked if called rapidly)
531
+ * The new Time object is initialized to the local timezone.
532
+ */
533
+ static struct mrb_time*
534
+ current_mrb_time(mrb_state *mrb)
535
+ {
536
+ struct mrb_time tmzero = {0}; /* Used to initialize the new mrb_time struct */
537
+ time_t sec, nsec;
538
+
539
+ #if defined(TIME_UTC) && !defined(__ANDROID__)
540
+ {
541
+ struct timespec ts;
542
+ timespec_get(&ts, TIME_UTC);
543
+ sec = ts.tv_sec;
544
+ nsec = ts.tv_nsec; /* Full nanosecond precision preserved */
545
+ }
546
+ #elif defined(USE_CLOCK_GETTIME)
547
+ {
548
+ struct timespec ts;
549
+ clock_gettime(CLOCK_REALTIME, &ts);
550
+ sec = ts.tv_sec;
551
+ nsec = ts.tv_nsec; /* Full nanosecond precision preserved */
552
+ }
553
+ #elif defined(NO_GETTIMEOFDAY)
554
+ {
555
+ static time_t last_sec = 0, last_usec = 0;
556
+
557
+ sec = time(NULL);
558
+ if (sec != last_sec) { /* Time has advanced by at least one second */
559
+ last_sec = sec;
560
+ last_usec = 0;
561
+ }
562
+ else { /* Called multiple times within the same second */
563
+ /* Add 1 usec to differentiate two Time objects created in rapid succession.
564
+ * This is a simple way to ensure distinctness when second-level precision is the best available.
565
+ * Note: This might lead to microsecond values that don't reflect actual time but ensure uniqueness.
566
+ */
567
+ last_usec += 1;
568
+ }
569
+ nsec = last_usec * NSECS_PER_USEC; /* Convert fake microseconds to nanoseconds */
570
+ }
571
+ #else
572
+ {
573
+ struct timeval tv;
574
+
575
+ gettimeofday(&tv, NULL);
576
+ sec = tv.tv_sec;
577
+ nsec = tv.tv_usec * NSECS_PER_USEC; /* Convert microseconds to nanoseconds */
578
+ }
579
+ #endif
580
+
581
+ struct mrb_time *tm = (struct mrb_time*)mrb_malloc(mrb, sizeof(*tm));
582
+ *tm = tmzero;
583
+ tm->sec = sec; tm->nsec = nsec;
584
+ tm->timezone = MRB_TIMEZONE_LOCAL;
585
+ time_update_datetime(mrb, tm, TRUE);
586
+
587
+ return tm;
588
+ }
589
+
590
+ /*
591
+ * call-seq:
592
+ * Time.now -> time
593
+ *
594
+ * Returns a new Time object representing the current system time.
595
+ * The time is created in the local timezone.
596
+ *
597
+ * Time.now #=> 2023-12-25 10:30:45 +0900
598
+ */
599
+ static mrb_value
600
+ time_now(mrb_state *mrb, mrb_value self)
601
+ {
602
+ return time_wrap(mrb, mrb_class_ptr(self), current_mrb_time(mrb));
603
+ }
604
+
605
+ MRB_API mrb_value
606
+ mrb_time_at(mrb_state *mrb, time_t sec, time_t usec, enum mrb_timezone zone)
607
+ {
608
+ time_t nsec;
609
+
610
+ /* Normalize microseconds to avoid overflow when converting to nanoseconds */
611
+ if (usec >= USECS_PER_SEC || usec <= -USECS_PER_SEC) {
612
+ time_t sec_adjustment = usec / USECS_PER_SEC;
613
+ usec -= sec_adjustment * USECS_PER_SEC;
614
+ sec += sec_adjustment;
615
+ }
616
+
617
+ nsec = usec * NSECS_PER_USEC;
618
+ return time_make_time(mrb, mrb_class_get_id(mrb, MRB_SYM(Time)), sec, nsec, zone);
619
+ }
620
+
621
+ /*
622
+ * call-seq:
623
+ * Time.at(seconds) -> time
624
+ * Time.at(seconds, microseconds) -> time
625
+ *
626
+ * Creates a new Time object representing the specified number of seconds
627
+ * since the Unix epoch (1970-01-01 00:00:00 UTC). The optional second
628
+ * argument specifies additional microseconds.
629
+ *
630
+ * Time.at(0) #=> 1970-01-01 09:00:00 +0900
631
+ * Time.at(1000000000) #=> 2001-09-09 10:46:40 +0900
632
+ * Time.at(1.5) #=> 1970-01-01 09:00:01 +0900 (with 500000 usec)
633
+ * Time.at(0, 500000) #=> 1970-01-01 09:00:00 +0900 (with 500000 usec)
634
+ */
635
+ static mrb_value
636
+ time_at_m(mrb_state *mrb, mrb_value self)
637
+ {
638
+ mrb_value sec;
639
+ mrb_value usec = mrb_fixnum_value(0);
640
+
641
+ mrb_get_args(mrb, "o|o", &sec, &usec);
642
+
643
+ return time_make(mrb, mrb_class_ptr(self), sec, usec, MRB_TIMEZONE_LOCAL);
644
+ }
645
+
646
+ static struct mrb_time*
647
+ time_mktime(mrb_state *mrb, mrb_int ayear, mrb_int amonth, mrb_int aday,
648
+ mrb_int ahour, mrb_int amin, mrb_int asec, mrb_int ausec,
649
+ enum mrb_timezone timezone)
650
+ {
651
+ struct tm nowtime = { 0 };
652
+
653
+ #if MRB_INT_MAX > INT_MAX
654
+ #define OUTINT(x) (((MRB_TIME_T_UINT ? 0 : INT_MIN) > (x)) || (x) > INT_MAX - TM_YEAR_BASE)
655
+ #else
656
+ #define OUTINT(x) 0
657
+ #endif
658
+
659
+ /* Check for underflow before adjusting year */
660
+ if (ayear < MRB_INT_MIN + TM_YEAR_BASE)
661
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "argument out of range");
662
+
663
+ /* Adjust year to be relative to TM_YEAR_BASE (1900) for struct tm */
664
+ ayear -= TM_YEAR_BASE;
665
+
666
+ /* Validate arguments: year (after adjustment), month, day, hour, minute, second.
667
+ * This checks for valid ranges for each component.
668
+ * For hour, it allows 24 only if minutes and seconds are zero (midnight).
669
+ * For second, it allows up to 60 to accommodate leap seconds.
670
+ */
671
+ if (OUTINT(ayear) ||
672
+ amonth < 1 || amonth > MONTHS_PER_YEAR ||
673
+ aday < 1 || aday > 31 || /* Max days in a month, could be more specific but 31 is a safe upper bound for validation */
674
+ ahour < 0 || ahour > HOURS_PER_DAY ||
675
+ (ahour == HOURS_PER_DAY && (amin > 0 || asec > 0)) || /* Allow 24:00:00 */
676
+ amin < 0 || amin > (MINS_PER_HOUR -1) ||
677
+ asec < 0 || asec > SECS_PER_MIN) /* tm_sec can be 60 for leap seconds */
678
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "argument out of range");
679
+
680
+ nowtime.tm_year = (int)ayear;
681
+ nowtime.tm_mon = (int)(amonth - 1); /* tm_mon is 0-11 */
682
+ nowtime.tm_mday = (int)aday;
683
+ nowtime.tm_hour = (int)ahour;
684
+ nowtime.tm_min = (int)amin;
685
+ nowtime.tm_sec = (int)asec;
686
+ nowtime.tm_isdst = -1;
687
+
688
+ time_t (*mk)(struct tm*);
689
+ if (timezone == MRB_TIMEZONE_UTC) {
690
+ mk = timegm;
691
+ }
692
+ else {
693
+ mk = mktime;
694
+ }
695
+
696
+ time_t nowsecs = (*mk)(&nowtime);
697
+ /*
698
+ * Handle mktime/timegm failure (returns -1):
699
+ * This could mean either:
700
+ * 1. Invalid date/time arguments, OR
701
+ * 2. Valid time exactly one second before Unix epoch (1969-12-31 23:59:59)
702
+ *
703
+ * To distinguish: increment seconds and test again.
704
+ * If result is 0 (epoch), original was valid epoch-1.
705
+ * Otherwise, original arguments were invalid.
706
+ */
707
+ if (nowsecs == (time_t)-1) {
708
+ struct tm test_tm = nowtime;
709
+ test_tm.tm_sec += 1;
710
+ if ((*mk)(&test_tm) != 0) {
711
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid time");
712
+ }
713
+ /* Original time was valid epoch-1, keep nowsecs = -1 */
714
+ }
715
+
716
+ return time_alloc_time(mrb, nowsecs, ausec * NSECS_PER_USEC, timezone);
717
+ }
718
+
719
+ /*
720
+ * call-seq:
721
+ * Time.gm(year, month = 1, day = 1, hour = 0, min = 0, sec = 0, usec = 0) -> time
722
+ * Time.utc(year, month = 1, day = 1, hour = 0, min = 0, sec = 0, usec = 0) -> time
723
+ *
724
+ * Creates a new Time object representing the specified date and time in UTC.
725
+ * All arguments except year are optional and default to the minimum value.
726
+ *
727
+ * Time.gm(2023) #=> 2023-01-01 00:00:00 UTC
728
+ * Time.gm(2023, 12, 25) #=> 2023-12-25 00:00:00 UTC
729
+ * Time.gm(2023, 12, 25, 10, 30) #=> 2023-12-25 10:30:00 UTC
730
+ * Time.utc(2023, 12, 25, 10, 30, 45) #=> 2023-12-25 10:30:45 UTC
731
+ */
732
+ static mrb_value
733
+ time_gm(mrb_state *mrb, mrb_value self)
734
+ {
735
+ mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0, amin = 0, asec = 0, ausec = 0;
736
+
737
+ mrb_get_args(mrb, "i|iiiiii",
738
+ &ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec);
739
+ return time_wrap(mrb, mrb_class_ptr(self),
740
+ time_mktime(mrb, ayear, amonth, aday, ahour, amin, asec, ausec, MRB_TIMEZONE_UTC));
741
+ }
742
+
743
+
744
+ /*
745
+ * call-seq:
746
+ * Time.local(year, month = 1, day = 1, hour = 0, min = 0, sec = 0, usec = 0) -> time
747
+ * Time.mktime(year, month = 1, day = 1, hour = 0, min = 0, sec = 0, usec = 0) -> time
748
+ *
749
+ * Creates a new Time object representing the specified date and time in the
750
+ * local timezone. All arguments except year are optional and default to
751
+ * the minimum value.
752
+ *
753
+ * Time.local(2023) #=> 2023-01-01 00:00:00 +0900
754
+ * Time.local(2023, 12, 25) #=> 2023-12-25 00:00:00 +0900
755
+ * Time.local(2023, 12, 25, 10, 30) #=> 2023-12-25 10:30:00 +0900
756
+ * Time.mktime(2023, 12, 25, 10, 30, 45) #=> 2023-12-25 10:30:45 +0900
757
+ */
758
+ static mrb_value
759
+ time_local(mrb_state *mrb, mrb_value self)
760
+ {
761
+ mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0, amin = 0, asec = 0, ausec = 0;
762
+
763
+ mrb_get_args(mrb, "i|iiiiii",
764
+ &ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec);
765
+ return time_wrap(mrb, mrb_class_ptr(self),
766
+ time_mktime(mrb, ayear, amonth, aday, ahour, amin, asec, ausec, MRB_TIMEZONE_LOCAL));
767
+ }
768
+
769
+ static struct mrb_time*
770
+ time_get_ptr(mrb_state *mrb, mrb_value time)
771
+ {
772
+ struct mrb_time *tm = DATA_GET_PTR(mrb, time, &time_type, struct mrb_time);
773
+ if (!tm) {
774
+ time_uninitialized(mrb);
775
+ }
776
+ return tm;
777
+ }
778
+
779
+ MRB_API struct tm*
780
+ mrb_time_get_tm(mrb_state *mrb, mrb_value time)
781
+ {
782
+ struct mrb_time *tm = time_get_ptr(mrb, time);
783
+ time_update_datetime(mrb, tm, FALSE);
784
+ return &tm->datetime;
785
+ }
786
+
787
+ /*
788
+ * call-seq:
789
+ * time == other_time -> true or false
790
+ * time.eql?(other_time) -> true or false
791
+ *
792
+ * Returns true if the two Time objects represent the same moment in time.
793
+ * Comparison is done at microsecond precision.
794
+ *
795
+ * t1 = Time.at(1000000000)
796
+ * t2 = Time.at(1000000000)
797
+ * t1 == t2 #=> true
798
+ * t1.eql?(t2) #=> true
799
+ */
800
+ static mrb_value
801
+ time_eq(mrb_state *mrb, mrb_value self)
802
+ {
803
+ mrb_value other = mrb_get_arg1(mrb);
804
+ struct mrb_time *tm1 = DATA_GET_PTR(mrb, self, &time_type, struct mrb_time);
805
+ struct mrb_time *tm2 = DATA_CHECK_GET_PTR(mrb, other, &time_type, struct mrb_time);
806
+ mrb_bool eq_p = tm1 && tm2 && tm1->sec == tm2->sec && tm1->nsec == tm2->nsec;
807
+
808
+ return mrb_bool_value(eq_p);
809
+ }
810
+
811
+ /*
812
+ * call-seq:
813
+ * time <=> other_time -> -1, 0, 1, or nil
814
+ *
815
+ * Compares two Time objects. Returns -1 if time is earlier than other_time,
816
+ * 0 if they are equal, 1 if time is later than other_time, or nil if
817
+ * other_time is not a Time object.
818
+ *
819
+ * t1 = Time.at(1000000000)
820
+ * t2 = Time.at(1000000001)
821
+ * t1 <=> t2 #=> -1
822
+ * t2 <=> t1 #=> 1
823
+ * t1 <=> t1 #=> 0
824
+ */
825
+ static mrb_value
826
+ time_cmp(mrb_state *mrb, mrb_value self)
827
+ {
828
+ mrb_value other = mrb_get_arg1(mrb);
829
+ struct mrb_time *tm1 = DATA_GET_PTR(mrb, self, &time_type, struct mrb_time);
830
+ struct mrb_time *tm2 = DATA_CHECK_GET_PTR(mrb, other, &time_type, struct mrb_time);
831
+
832
+ if (!tm1 || !tm2) return mrb_nil_value();
833
+ if (tm1->sec > tm2->sec) {
834
+ return mrb_fixnum_value(1);
835
+ }
836
+ else if (tm1->sec < tm2->sec) {
837
+ return mrb_fixnum_value(-1);
838
+ }
839
+ /* tm1->sec == tm2->sec */
840
+ if (tm1->nsec > tm2->nsec) {
841
+ return mrb_fixnum_value(1);
842
+ }
843
+ else if (tm1->nsec < tm2->nsec) {
844
+ return mrb_fixnum_value(-1);
845
+ }
846
+ return mrb_fixnum_value(0);
847
+ }
848
+
849
+ static mrb_noreturn void
850
+ int_overflow(mrb_state *mrb, const char *reason)
851
+ {
852
+ mrb_raisef(mrb, E_RANGE_ERROR, "Time out of range in %s", reason);
853
+ }
854
+
855
+ /*
856
+ * call-seq:
857
+ * time + numeric -> time
858
+ *
859
+ * Returns a new Time object representing time + numeric seconds.
860
+ * The numeric can be an Integer, Float, or other numeric type.
861
+ *
862
+ * t = Time.at(1000000000)
863
+ * t + 1 #=> 2001-09-09 10:46:41 +0900
864
+ * t + 0.5 #=> 2001-09-09 10:46:40 +0900 (with 500000 usec)
865
+ * t + 3600 #=> 2001-09-09 11:46:40 +0900 (one hour later)
866
+ */
867
+ static mrb_value
868
+ time_plus(mrb_state *mrb, mrb_value self)
869
+ {
870
+ mrb_value o = mrb_get_arg1(mrb);
871
+ time_t sec, usec;
872
+
873
+ struct mrb_time *tm = time_get_ptr(mrb, self);
874
+ sec = mrb_to_time_t(mrb, o, &usec);
875
+ #ifdef MRB_HAVE_TYPE_GENERIC_CHECKED_ARITHMETIC_BUILTINS
876
+ /*
877
+ * Add seconds and handle potential overflow.
878
+ * If __builtin_add_overflow is available (GCC/Clang extension), use it for safe addition.
879
+ * Otherwise, perform manual overflow checks before addition.
880
+ */
881
+ if (__builtin_add_overflow(tm->sec, sec, &sec)) { /* sec result is stored back in sec */
882
+ int_overflow(mrb, "addition");
883
+ }
884
+ #else
885
+ if (sec >= 0) { /* Adding a positive number */
886
+ if (tm->sec > MRB_TIME_MAX - sec) { /* Check for positive overflow */
887
+ int_overflow(mrb, "addition");
888
+ }
889
+ }
890
+ else { /* Adding a negative number (effectively subtraction) */
891
+ if (tm->sec < MRB_TIME_MIN - sec) { /* Check for negative overflow */
892
+ int_overflow(mrb, "addition");
893
+ }
894
+ }
895
+ sec = tm->sec + sec; /* Perform the addition */
896
+ #endif
897
+ return time_make_time(mrb, mrb_obj_class(mrb, self), sec, tm->nsec + usec * NSECS_PER_USEC, tm->timezone);
898
+ }
899
+
900
+ /*
901
+ * call-seq:
902
+ * time - other_time -> float
903
+ * time - numeric -> time
904
+ *
905
+ * If other_time is a Time object, returns the difference in seconds as a Float.
906
+ * If numeric is given, returns a new Time object representing time - numeric seconds.
907
+ *
908
+ * t1 = Time.at(1000000000)
909
+ * t2 = Time.at(1000000001)
910
+ * t2 - t1 #=> 1.0
911
+ * t1 - 1 #=> 2001-09-09 10:46:39 +0900
912
+ * t1 - 0.5 #=> 2001-09-09 10:46:39 +0900 (with 500000 usec)
913
+ */
914
+ static mrb_value
915
+ time_minus(mrb_state *mrb, mrb_value self)
916
+ {
917
+ mrb_value other = mrb_get_arg1(mrb);
918
+ struct mrb_time *tm = time_get_ptr(mrb, self);
919
+ struct mrb_time *tm2 = DATA_CHECK_GET_PTR(mrb, other, &time_type, struct mrb_time);
920
+
921
+ if (tm2) {
922
+ #ifndef MRB_NO_FLOAT
923
+ mrb_float f;
924
+ f = (mrb_float)(tm->sec - tm2->sec)
925
+ + (mrb_float)(tm->nsec - tm2->nsec) / 1.0e9;
926
+ return mrb_float_value(mrb, f);
927
+ #else
928
+ mrb_int f = tm->sec - tm2->sec;
929
+ if (tm->nsec < tm2->nsec) f--;
930
+ return mrb_int_value(mrb, f);
931
+ #endif
932
+ }
933
+ else {
934
+ time_t sec, usec;
935
+ sec = mrb_to_time_t(mrb, other, &usec);
936
+ #ifdef MRB_HAVE_TYPE_GENERIC_CHECKED_ARITHMETIC_BUILTINS
937
+ /*
938
+ * Subtract seconds and handle potential overflow.
939
+ * If __builtin_sub_overflow is available, use it.
940
+ * Otherwise, perform manual overflow checks. Note that `sec` here is the subtrahend.
941
+ */
942
+ if (__builtin_sub_overflow(tm->sec, sec, &sec)) { /* sec result is stored back in sec */
943
+ int_overflow(mrb, "subtraction");
944
+ }
945
+ #else
946
+ if (sec >= 0) { /* Subtracting a positive number */
947
+ if (tm->sec < MRB_TIME_MIN + sec) { /* Check for negative overflow */
948
+ int_overflow(mrb, "subtraction");
949
+ }
950
+ }
951
+ else { /* Subtracting a negative number (effectively addition) */
952
+ if (tm->sec > MRB_TIME_MAX + sec) { /* Check for positive overflow */
953
+ int_overflow(mrb, "subtraction");
954
+ }
955
+ }
956
+ sec = tm->sec - sec; /* Perform the subtraction */
957
+ #endif
958
+ return time_make_time(mrb, mrb_obj_class(mrb, self), sec, tm->nsec - usec * NSECS_PER_USEC, tm->timezone);
959
+ }
960
+ }
961
+
962
+ /*
963
+ * call-seq:
964
+ * time.wday -> integer
965
+ *
966
+ * Returns the day of the week (0-6) of the time, where Sunday is 0.
967
+ *
968
+ * Time.local(2023, 12, 25).wday #=> 1 (Monday)
969
+ * Time.local(2023, 12, 24).wday #=> 0 (Sunday)
970
+ * Time.local(2023, 12, 30).wday #=> 6 (Saturday)
971
+ */
972
+ static mrb_value
973
+ time_wday(mrb_state *mrb, mrb_value self)
974
+ {
975
+ struct mrb_time *tm = time_get_ptr(mrb, self);
976
+ return mrb_fixnum_value(tm->datetime.tm_wday);
977
+ }
978
+
979
+ /*
980
+ * call-seq:
981
+ * time.yday -> integer
982
+ *
983
+ * Returns the day of the year (1-366) of the time.
984
+ *
985
+ * Time.local(2023, 1, 1).yday #=> 1
986
+ * Time.local(2023, 12, 31).yday #=> 365
987
+ * Time.local(2024, 12, 31).yday #=> 366 (leap year)
988
+ */
989
+ static mrb_value
990
+ time_yday(mrb_state *mrb, mrb_value self)
991
+ {
992
+ struct mrb_time *tm = time_get_ptr(mrb, self);
993
+ return mrb_fixnum_value(tm->datetime.tm_yday + 1);
994
+ }
995
+
996
+ /*
997
+ * call-seq:
998
+ * time.year -> integer
999
+ *
1000
+ * Returns the year of the time.
1001
+ *
1002
+ * Time.local(2023, 12, 25).year #=> 2023
1003
+ * Time.at(0).year #=> 1970
1004
+ */
1005
+ static mrb_value
1006
+ time_year(mrb_state *mrb, mrb_value self)
1007
+ {
1008
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1009
+ return mrb_fixnum_value(tm->datetime.tm_year + TM_YEAR_BASE);
1010
+ }
1011
+
1012
+ static size_t
1013
+ time_zonename(mrb_state *mrb, struct mrb_time *tm, char *buf, size_t len)
1014
+ {
1015
+ #ifdef MRB_TIME_WINDOWS_NO_STRFTIME_Z
1016
+ /*
1017
+ * On some Windows versions (specifically with MSC_VER < 1900, i.e., pre-VS2015, or MinGW),
1018
+ * strftime's "%z" (timezone offset) specifier might not be available or reliable.
1019
+ * This block manually calculates the UTC offset.
1020
+ */
1021
+ struct tm datetime = {0}; /* Temporary tm struct for strftime */
1022
+ time_t utc_sec = timegm(&tm->datetime); /* Convert current datetime (interpreted as UTC) to time_t */
1023
+ /* Calculate offset in minutes: difference between this UTC time_t and the stored local time_t */
1024
+ int offset = abs((int)(utc_sec - tm->sec) / SECS_PER_MIN);
1025
+ /* Copy actual date components for accurate timezone/DST calculation */
1026
+ datetime.tm_year = tm->datetime.tm_year;
1027
+ datetime.tm_mon = tm->datetime.tm_mon;
1028
+ datetime.tm_mday = tm->datetime.tm_mday;
1029
+ datetime.tm_hour = offset / MINS_PER_HOUR; /* Convert offset to hours and minutes */
1030
+ datetime.tm_min = offset % MINS_PER_HOUR;
1031
+ buf[0] = utc_sec < tm->sec ? '-' : '+'; /* Determine sign of the offset */
1032
+ return strftime(buf+1, len-1, "%H%M", &datetime) + 1; /* Format as +HHMM or -HHMM */
1033
+ #else
1034
+ /* On other systems, use strftime with "%z" to get the timezone offset */
1035
+ return strftime(buf, len, "%z", &tm->datetime);
1036
+ #endif
1037
+ }
1038
+
1039
+ /*
1040
+ * call-seq:
1041
+ * time.zone -> string
1042
+ *
1043
+ * Returns the timezone name or offset of the time.
1044
+ * For UTC times, returns "UTC". For local times, returns the
1045
+ * timezone offset in the format "+HHMM" or "-HHMM".
1046
+ *
1047
+ * Time.utc(2023, 12, 25).zone #=> "UTC"
1048
+ * Time.local(2023, 12, 25).zone #=> "+0900" (example for JST)
1049
+ */
1050
+ static mrb_value
1051
+ time_zone(mrb_state *mrb, mrb_value self)
1052
+ {
1053
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1054
+ if (tm->timezone == MRB_TIMEZONE_UTC) {
1055
+ return mrb_str_new_lit(mrb, "UTC");
1056
+ }
1057
+ char buf[64];
1058
+ size_t len = time_zonename(mrb, tm, buf, sizeof(buf));
1059
+ return mrb_str_new(mrb, buf, len);
1060
+ }
1061
+
1062
+ /*
1063
+ * call-seq:
1064
+ * time.asctime -> string
1065
+ * time.ctime -> string
1066
+ *
1067
+ * Returns a string representation of the time in the classic Unix
1068
+ * asctime format: "Day Mon DD HH:MM:SS YYYY".
1069
+ *
1070
+ * Time.local(2023, 12, 25, 10, 30, 45).asctime #=> "Mon Dec 25 10:30:45 2023"
1071
+ * Time.utc(2023, 1, 1, 0, 0, 0).ctime #=> "Sun Jan 1 00:00:00 2023"
1072
+ */
1073
+ static mrb_value
1074
+ time_asctime(mrb_state *mrb, mrb_value self)
1075
+ {
1076
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1077
+ struct tm *d = &tm->datetime;
1078
+ int len;
1079
+
1080
+ #if defined(MRB_NO_STDIO)
1081
+ # ifdef NO_ASCTIME_R
1082
+ char *buf = asctime(d);
1083
+ # else
1084
+ char buf[32], *s;
1085
+ s = asctime_r(d, buf);
1086
+ # endif
1087
+ len = strlen(buf)-1; /* truncate the last newline */
1088
+ #else
1089
+ char buf[32];
1090
+
1091
+ len = snprintf(buf, sizeof(buf), "%s %s %2d %02d:%02d:%02d %.4d",
1092
+ wday_names[d->tm_wday], mon_names[d->tm_mon], d->tm_mday,
1093
+ d->tm_hour, d->tm_min, d->tm_sec,
1094
+ d->tm_year + TM_YEAR_BASE);
1095
+ #endif
1096
+ return mrb_str_new(mrb, buf, len);
1097
+ }
1098
+
1099
+ /*
1100
+ * call-seq:
1101
+ * time.day -> integer
1102
+ * time.mday -> integer
1103
+ *
1104
+ * Returns the day of the month (1-31) of the time.
1105
+ *
1106
+ * Time.local(2023, 12, 25).day #=> 25
1107
+ * Time.local(2023, 1, 1).mday #=> 1
1108
+ */
1109
+ static mrb_value
1110
+ time_day(mrb_state *mrb, mrb_value self)
1111
+ {
1112
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1113
+ return mrb_fixnum_value(tm->datetime.tm_mday);
1114
+ }
1115
+
1116
+
1117
+ /*
1118
+ * call-seq:
1119
+ * time.dst? -> true or false
1120
+ *
1121
+ * Returns true if daylight saving time is in effect for this time,
1122
+ * false otherwise. Only meaningful for local times.
1123
+ *
1124
+ * # Example depends on local timezone and DST rules
1125
+ * Time.local(2023, 7, 15).dst? #=> true (summer in northern hemisphere)
1126
+ * Time.local(2023, 1, 15).dst? #=> false (winter in northern hemisphere)
1127
+ * Time.utc(2023, 7, 15).dst? #=> false (UTC has no DST)
1128
+ */
1129
+ static mrb_value
1130
+ time_dst_p(mrb_state *mrb, mrb_value self)
1131
+ {
1132
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1133
+ return mrb_bool_value(tm->datetime.tm_isdst);
1134
+ }
1135
+
1136
+ /*
1137
+ * call-seq:
1138
+ * time.getutc -> time
1139
+ * time.getgm -> time
1140
+ *
1141
+ * Returns a new Time object representing the same moment in UTC timezone.
1142
+ * The original time object is not modified.
1143
+ *
1144
+ * t = Time.local(2023, 12, 25, 10, 30) #=> 2023-12-25 10:30:00 +0900
1145
+ * t.getutc #=> 2023-12-25 01:30:00 UTC
1146
+ * t #=> 2023-12-25 10:30:00 +0900 (unchanged)
1147
+ */
1148
+ static mrb_value
1149
+ time_getutc(mrb_state *mrb, mrb_value self)
1150
+ {
1151
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1152
+ struct mrb_time *tm2 = (struct mrb_time*)mrb_malloc(mrb, sizeof(*tm));
1153
+ *tm2 = *tm;
1154
+ if (tm2->timezone != MRB_TIMEZONE_UTC) {
1155
+ tm2->timezone = MRB_TIMEZONE_UTC;
1156
+ time_update_datetime(mrb, tm2, TRUE);
1157
+ }
1158
+ return time_wrap(mrb, mrb_obj_class(mrb, self), tm2);
1159
+ }
1160
+
1161
+ /*
1162
+ * call-seq:
1163
+ * time.getlocal -> time
1164
+ *
1165
+ * Returns a new Time object representing the same moment in local timezone.
1166
+ * The original time object is not modified.
1167
+ *
1168
+ * t = Time.utc(2023, 12, 25, 1, 30) #=> 2023-12-25 01:30:00 UTC
1169
+ * t.getlocal #=> 2023-12-25 10:30:00 +0900
1170
+ * t #=> 2023-12-25 01:30:00 UTC (unchanged)
1171
+ */
1172
+ static mrb_value
1173
+ time_getlocal(mrb_state *mrb, mrb_value self)
1174
+ {
1175
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1176
+ struct mrb_time *tm2 = (struct mrb_time*)mrb_malloc(mrb, sizeof(*tm));
1177
+ *tm2 = *tm;
1178
+ if (tm2->timezone != MRB_TIMEZONE_LOCAL) {
1179
+ tm2->timezone = MRB_TIMEZONE_LOCAL;
1180
+ time_update_datetime(mrb, tm2, TRUE);
1181
+ }
1182
+ return time_wrap(mrb, mrb_obj_class(mrb, self), tm2);
1183
+ }
1184
+
1185
+ /*
1186
+ * call-seq:
1187
+ * time.hour -> integer
1188
+ *
1189
+ * Returns the hour of the day (0-23) of the time.
1190
+ *
1191
+ * Time.local(2023, 12, 25, 10, 30).hour #=> 10
1192
+ * Time.local(2023, 12, 25, 0, 0).hour #=> 0
1193
+ * Time.local(2023, 12, 25, 23, 59).hour #=> 23
1194
+ */
1195
+ static mrb_value
1196
+ time_hour(mrb_state *mrb, mrb_value self)
1197
+ {
1198
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1199
+ return mrb_fixnum_value(tm->datetime.tm_hour);
1200
+ }
1201
+
1202
+ /*
1203
+ * call-seq:
1204
+ * Time.new -> time
1205
+ * Time.new(year, month = 1, day = 1, hour = 0, min = 0, sec = 0, usec = 0) -> time
1206
+ *
1207
+ * Creates a new Time object. With no arguments, creates a Time representing
1208
+ * the current moment. With arguments, creates a Time representing the
1209
+ * specified date and time in the local timezone.
1210
+ *
1211
+ * Time.new #=> 2023-12-25 10:30:45 +0900 (current time)
1212
+ * Time.new(2023) #=> 2023-01-01 00:00:00 +0900
1213
+ * Time.new(2023, 12, 25) #=> 2023-12-25 00:00:00 +0900
1214
+ * Time.new(2023, 12, 25, 10, 30, 45) #=> 2023-12-25 10:30:45 +0900
1215
+ */
1216
+ static mrb_value
1217
+ time_init(mrb_state *mrb, mrb_value self)
1218
+ {
1219
+ mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0,
1220
+ amin = 0, asec = 0, ausec = 0;
1221
+
1222
+ mrb_int n = mrb_get_args(mrb, "|iiiiiii", /* year, month, day, hour, minute, second, microsecond (all optional) */
1223
+ &ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec);
1224
+ struct mrb_time *tm = (struct mrb_time*)DATA_PTR(self);
1225
+
1226
+ if (tm) { /* If Time object is being re-initialized (e.g. time_obj.send(:initialize, ...)) */
1227
+ mrb_free(mrb, tm); /* Free existing data */
1228
+ }
1229
+ mrb_data_init(self, NULL, &time_type); /* Prepare for new data */
1230
+
1231
+ if (n == 0) { /* Time.new (no arguments) */
1232
+ tm = current_mrb_time(mrb); /* Get current time */
1233
+ }
1234
+ else { /* Time.new(year, [mon, day, hour, min, sec, usec]) */
1235
+ /* Create time from specified components in local timezone */
1236
+ tm = time_mktime(mrb, ayear, amonth, aday, ahour, amin, asec, ausec, MRB_TIMEZONE_LOCAL);
1237
+ }
1238
+ mrb_data_init(self, tm, &time_type); /* Attach the new mrb_time struct to the mruby object */
1239
+ return self;
1240
+ }
1241
+
1242
+ /*
1243
+ * call-seq:
1244
+ * time.initialize_copy(other_time) -> time
1245
+ *
1246
+ * Initializes this time object as a copy of other_time.
1247
+ * This is a private method used internally by dup and clone.
1248
+ *
1249
+ * t1 = Time.now
1250
+ * t2 = t1.dup # calls initialize_copy internally
1251
+ */
1252
+ static mrb_value
1253
+ time_init_copy(mrb_state *mrb, mrb_value copy)
1254
+ {
1255
+ mrb_value src = mrb_get_arg1(mrb);
1256
+
1257
+ if (mrb_obj_equal(mrb, copy, src)) return copy;
1258
+ if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) {
1259
+ mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class");
1260
+ }
1261
+ struct mrb_time *t1 = (struct mrb_time*)DATA_PTR(copy);
1262
+ struct mrb_time *t2 = (struct mrb_time*)DATA_PTR(src);
1263
+
1264
+ if (!t2) {
1265
+ time_uninitialized(mrb);
1266
+ }
1267
+ if (!t1) {
1268
+ t1 = (struct mrb_time*)mrb_malloc(mrb, sizeof(struct mrb_time));
1269
+ mrb_data_init(copy, t1, &time_type);
1270
+ }
1271
+ *t1 = *t2;
1272
+ return copy;
1273
+ }
1274
+
1275
+ /*
1276
+ * call-seq:
1277
+ * time.localtime -> time
1278
+ *
1279
+ * Converts the time to local timezone in place and returns self.
1280
+ * The time value remains the same, but the timezone is changed to local.
1281
+ *
1282
+ * t = Time.utc(2023, 12, 25, 1, 30) #=> 2023-12-25 01:30:00 UTC
1283
+ * t.localtime #=> 2023-12-25 10:30:00 +0900
1284
+ * t #=> 2023-12-25 10:30:00 +0900 (modified)
1285
+ */
1286
+ static mrb_value
1287
+ time_localtime(mrb_state *mrb, mrb_value self)
1288
+ {
1289
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1290
+ tm->timezone = MRB_TIMEZONE_LOCAL;
1291
+ time_update_datetime(mrb, tm, FALSE);
1292
+ return self;
1293
+ }
1294
+
1295
+
1296
+ /*
1297
+ * call-seq:
1298
+ * time.min -> integer
1299
+ *
1300
+ * Returns the minute of the hour (0-59) of the time.
1301
+ *
1302
+ * Time.local(2023, 12, 25, 10, 30).min #=> 30
1303
+ * Time.local(2023, 12, 25, 10, 0).min #=> 0
1304
+ * Time.local(2023, 12, 25, 10, 59).min #=> 59
1305
+ */
1306
+ static mrb_value
1307
+ time_min(mrb_state *mrb, mrb_value self)
1308
+ {
1309
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1310
+ return mrb_fixnum_value(tm->datetime.tm_min);
1311
+ }
1312
+
1313
+ /*
1314
+ * call-seq:
1315
+ * time.mon -> integer
1316
+ * time.month -> integer
1317
+ *
1318
+ * Returns the month of the year (1-12) of the time.
1319
+ *
1320
+ * Time.local(2023, 12, 25).mon #=> 12
1321
+ * Time.local(2023, 1, 1).month #=> 1
1322
+ */
1323
+ static mrb_value
1324
+ time_mon(mrb_state *mrb, mrb_value self)
1325
+ {
1326
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1327
+ return mrb_fixnum_value(tm->datetime.tm_mon + 1);
1328
+ }
1329
+
1330
+ /*
1331
+ * call-seq:
1332
+ * time.sec -> integer
1333
+ *
1334
+ * Returns the second of the minute (0-60) of the time.
1335
+ * Note: 60 is possible for leap seconds.
1336
+ *
1337
+ * Time.local(2023, 12, 25, 10, 30, 45).sec #=> 45
1338
+ * Time.local(2023, 12, 25, 10, 30, 0).sec #=> 0
1339
+ * Time.local(2023, 12, 25, 10, 30, 59).sec #=> 59
1340
+ */
1341
+ static mrb_value
1342
+ time_sec(mrb_state *mrb, mrb_value self)
1343
+ {
1344
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1345
+ return mrb_fixnum_value(tm->datetime.tm_sec);
1346
+ }
1347
+
1348
+ #ifndef MRB_NO_FLOAT
1349
+ /*
1350
+ * call-seq:
1351
+ * time.to_f -> float
1352
+ *
1353
+ * Returns the time as a Float representing the number of seconds
1354
+ * since the Unix epoch (1970-01-01 00:00:00 UTC), including
1355
+ * fractional seconds for microsecond precision.
1356
+ *
1357
+ * Time.at(0).to_f #=> 0.0
1358
+ * Time.at(1000000000.5).to_f #=> 1000000000.5
1359
+ * Time.at(0, 123456).to_f #=> 0.123456
1360
+ */
1361
+ static mrb_value
1362
+ time_to_f(mrb_state *mrb, mrb_value self)
1363
+ {
1364
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1365
+ return mrb_float_value(mrb, (mrb_float)tm->sec + (mrb_float)tm->nsec/1.0e9);
1366
+ }
1367
+ #endif
1368
+
1369
+ /*
1370
+ * call-seq:
1371
+ * time.to_i -> integer
1372
+ *
1373
+ * Returns the time as an integer representing the number of seconds
1374
+ * since the Unix epoch (1970-01-01 00:00:00 UTC).
1375
+ *
1376
+ * Time.at(0).to_i #=> 0
1377
+ * Time.at(1000000000).to_i #=> 1000000000
1378
+ * Time.local(2023, 1, 1).to_i #=> 1672531200 (example)
1379
+ */
1380
+ static mrb_value
1381
+ time_to_i(mrb_state *mrb, mrb_value self)
1382
+ {
1383
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1384
+ return time_value_from_time_t(mrb, tm->sec);
1385
+ }
1386
+
1387
+ /*
1388
+ * call-seq:
1389
+ * time.usec -> integer
1390
+ *
1391
+ * Returns the microsecond component (0-999999) of the time.
1392
+ *
1393
+ * Time.at(1000000000.123456).usec #=> 123456
1394
+ * Time.at(1000000000, 500000).usec #=> 500000
1395
+ * Time.at(1000000000).usec #=> 0
1396
+ */
1397
+ static mrb_value
1398
+ time_usec(mrb_state *mrb, mrb_value self)
1399
+ {
1400
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1401
+ return mrb_fixnum_value((mrb_int)(tm->nsec / NSECS_PER_USEC));
1402
+ }
1403
+
1404
+ /*
1405
+ * call-seq:
1406
+ * time.nsec -> integer
1407
+ * time.tv_nsec -> integer
1408
+ *
1409
+ * Returns the nanosecond component (0-999999999) of the time.
1410
+ *
1411
+ * Time.at(1000000000, 123456).nsec #=> 123456000
1412
+ * Time.at(1000000000.123456789).nsec #=> 123456789
1413
+ * Time.at(1000000000).nsec #=> 0
1414
+ */
1415
+ static mrb_value
1416
+ time_nsec(mrb_state *mrb, mrb_value self)
1417
+ {
1418
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1419
+ return mrb_fixnum_value((mrb_int)tm->nsec);
1420
+ }
1421
+
1422
+ /*
1423
+ * call-seq:
1424
+ * time.utc -> time
1425
+ * time.gmtime -> time
1426
+ *
1427
+ * Converts the time to UTC timezone in place and returns self.
1428
+ * The time value remains the same, but the timezone is changed to UTC.
1429
+ *
1430
+ * t = Time.local(2023, 12, 25, 10, 30) #=> 2023-12-25 10:30:00 +0900
1431
+ * t.utc #=> 2023-12-25 01:30:00 UTC
1432
+ * t #=> 2023-12-25 01:30:00 UTC (modified)
1433
+ */
1434
+ static mrb_value
1435
+ time_utc(mrb_state *mrb, mrb_value self)
1436
+ {
1437
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1438
+ tm->timezone = MRB_TIMEZONE_UTC;
1439
+ time_update_datetime(mrb, tm, FALSE);
1440
+ return self;
1441
+ }
1442
+
1443
+ /*
1444
+ * call-seq:
1445
+ * time.utc? -> true or false
1446
+ * time.gmt? -> true or false
1447
+ *
1448
+ * Returns true if the time is in UTC timezone, false otherwise.
1449
+ *
1450
+ * Time.utc(2023, 12, 25).utc? #=> true
1451
+ * Time.local(2023, 12, 25).utc? #=> false
1452
+ * Time.local(2023, 12, 25).gmt? #=> false
1453
+ */
1454
+ static mrb_value
1455
+ time_utc_p(mrb_state *mrb, mrb_value self)
1456
+ {
1457
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1458
+ return mrb_bool_value(tm->timezone == MRB_TIMEZONE_UTC);
1459
+ }
1460
+
1461
+ /*
1462
+ * call-seq:
1463
+ * time.to_s -> string
1464
+ * time.inspect -> string
1465
+ *
1466
+ * Returns a string representation of the time in the format
1467
+ * "YYYY-MM-DD HH:MM:SS ZONE".
1468
+ *
1469
+ * Time.local(2023, 12, 25, 10, 30, 45).to_s #=> "2023-12-25 10:30:45 +0900"
1470
+ * Time.utc(2023, 12, 25, 10, 30, 45).to_s #=> "2023-12-25 10:30:45 UTC"
1471
+ */
1472
+ static mrb_value
1473
+ time_to_s(mrb_state *mrb, mrb_value self)
1474
+ {
1475
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1476
+ char buf[64];
1477
+ size_t len;
1478
+
1479
+ if (tm->timezone == MRB_TIMEZONE_UTC) {
1480
+ len = strftime(buf, sizeof(buf), TO_S_FMT "UTC", &tm->datetime);
1481
+ }
1482
+ else {
1483
+ #ifdef MRB_TIME_WINDOWS_NO_STRFTIME_Z
1484
+ /* Use two-step approach on Windows platforms without reliable %z support */
1485
+ len = strftime(buf, sizeof(buf), TO_S_FMT, &tm->datetime);
1486
+ len += time_zonename(mrb, tm, buf+len, sizeof(buf)-len);
1487
+ #else
1488
+ /* Use combined format string on platforms with %z support */
1489
+ len = strftime(buf, sizeof(buf), TO_S_FMT "%z", &tm->datetime);
1490
+ #endif
1491
+ }
1492
+ mrb_value str = mrb_str_new(mrb, buf, len);
1493
+ RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
1494
+ return str;
1495
+ }
1496
+
1497
+ /*
1498
+ * call-seq:
1499
+ * time.hash -> integer
1500
+ *
1501
+ * Returns a hash value for the time object. Two time objects with
1502
+ * the same time value will have the same hash value.
1503
+ *
1504
+ * t1 = Time.at(1000000000)
1505
+ * t2 = Time.at(1000000000)
1506
+ * t1.hash == t2.hash #=> true
1507
+ */
1508
+ static mrb_value
1509
+ time_hash(mrb_state *mrb, mrb_value self)
1510
+ {
1511
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1512
+ uint32_t hash = mrb_byte_hash((uint8_t*)&tm->sec, sizeof(time_t));
1513
+ hash = mrb_byte_hash_step((uint8_t*)&tm->nsec, sizeof(time_t), hash);
1514
+ hash = mrb_byte_hash_step((uint8_t*)&tm->timezone, sizeof(tm->timezone), hash);
1515
+ return mrb_int_value(mrb, hash);
1516
+ }
1517
+
1518
+ /*
1519
+ * Generic function for weekday checks. Used by all weekday methods.
1520
+ */
1521
+ static mrb_value
1522
+ time_wday_p(mrb_state *mrb, mrb_value self, int target_wday)
1523
+ {
1524
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1525
+ return mrb_bool_value(tm->datetime.tm_wday == target_wday);
1526
+ }
1527
+
1528
+ /*
1529
+ * call-seq:
1530
+ * time.sunday? -> true or false
1531
+ *
1532
+ * Returns true if the time falls on a Sunday, false otherwise.
1533
+ *
1534
+ * Time.local(2023, 12, 24).sunday? #=> true
1535
+ * Time.local(2023, 12, 25).sunday? #=> false
1536
+ */
1537
+ static mrb_value
1538
+ time_sunday(mrb_state *mrb, mrb_value self)
1539
+ {
1540
+ return time_wday_p(mrb, self, 0);
1541
+ }
1542
+
1543
+ /*
1544
+ * call-seq:
1545
+ * time.monday? -> true or false
1546
+ *
1547
+ * Returns true if the time falls on a Monday, false otherwise.
1548
+ *
1549
+ * Time.local(2023, 12, 25).monday? #=> true
1550
+ * Time.local(2023, 12, 24).monday? #=> false
1551
+ */
1552
+ static mrb_value
1553
+ time_monday(mrb_state *mrb, mrb_value self)
1554
+ {
1555
+ return time_wday_p(mrb, self, 1);
1556
+ }
1557
+
1558
+ /*
1559
+ * call-seq:
1560
+ * time.tuesday? -> true or false
1561
+ *
1562
+ * Returns true if the time falls on a Tuesday, false otherwise.
1563
+ *
1564
+ * Time.local(2023, 12, 26).tuesday? #=> true
1565
+ * Time.local(2023, 12, 25).tuesday? #=> false
1566
+ */
1567
+ static mrb_value
1568
+ time_tuesday(mrb_state *mrb, mrb_value self)
1569
+ {
1570
+ return time_wday_p(mrb, self, 2);
1571
+ }
1572
+
1573
+ /*
1574
+ * call-seq:
1575
+ * time.wednesday? -> true or false
1576
+ *
1577
+ * Returns true if the time falls on a Wednesday, false otherwise.
1578
+ *
1579
+ * Time.local(2023, 12, 27).wednesday? #=> true
1580
+ * Time.local(2023, 12, 25).wednesday? #=> false
1581
+ */
1582
+ static mrb_value
1583
+ time_wednesday(mrb_state *mrb, mrb_value self)
1584
+ {
1585
+ return time_wday_p(mrb, self, 3);
1586
+ }
1587
+
1588
+ /*
1589
+ * call-seq:
1590
+ * time.thursday? -> true or false
1591
+ *
1592
+ * Returns true if the time falls on a Thursday, false otherwise.
1593
+ *
1594
+ * Time.local(2023, 12, 28).thursday? #=> true
1595
+ * Time.local(2023, 12, 25).thursday? #=> false
1596
+ */
1597
+ static mrb_value
1598
+ time_thursday(mrb_state *mrb, mrb_value self)
1599
+ {
1600
+ return time_wday_p(mrb, self, 4);
1601
+ }
1602
+
1603
+ /*
1604
+ * call-seq:
1605
+ * time.friday? -> true or false
1606
+ *
1607
+ * Returns true if the time falls on a Friday, false otherwise.
1608
+ *
1609
+ * Time.local(2023, 12, 29).friday? #=> true
1610
+ * Time.local(2023, 12, 25).friday? #=> false
1611
+ */
1612
+ static mrb_value
1613
+ time_friday(mrb_state *mrb, mrb_value self)
1614
+ {
1615
+ return time_wday_p(mrb, self, 5);
1616
+ }
1617
+
1618
+ /*
1619
+ * call-seq:
1620
+ * time.saturday? -> true or false
1621
+ *
1622
+ * Returns true if the time falls on a Saturday, false otherwise.
1623
+ *
1624
+ * Time.local(2023, 12, 30).saturday? #=> true
1625
+ * Time.local(2023, 12, 25).saturday? #=> false
1626
+ */
1627
+ static mrb_value
1628
+ time_saturday(mrb_state *mrb, mrb_value self)
1629
+ {
1630
+ return time_wday_p(mrb, self, 6);
1631
+ }
1632
+
1633
+ /*
1634
+ * ISO 15.2.19.7.12
1635
+ * ISO 15.2.19.7.14
1636
+ * ISO 15.2.19.7.29
1637
+ */
1638
+ /*
1639
+ * call-seq:
1640
+ * time.gmt_offset -> integer
1641
+ * time.utc_offset -> integer
1642
+ * time.gmtoff -> integer
1643
+ *
1644
+ * Returns the offset in seconds between the timezone of time and UTC.
1645
+ *
1646
+ * Time.local(2000, 1, 1).gmt_offset #=> 32400 (JST: UTC+9)
1647
+ * Time.utc(2000, 1, 1).utc_offset #=> 0 (UTC)
1648
+ * Time.local(2000, 7, 1).gmtoff #=> 32400 (or 28800 if DST)
1649
+ */
1650
+ static mrb_value
1651
+ time_utc_offset(mrb_state *mrb, mrb_value self)
1652
+ {
1653
+ struct mrb_time *tm = time_get_ptr(mrb, self);
1654
+
1655
+ if (tm->timezone == MRB_TIMEZONE_UTC) {
1656
+ return mrb_fixnum_value(0); /* UTC is always offset 0 */
1657
+ }
1658
+
1659
+ /* For local times, calculate offset = local_time_t - utc_time_t */
1660
+ time_t utc_time_t = timegm(&tm->datetime); /* Convert datetime as UTC */
1661
+ mrb_int offset_seconds = (mrb_int)(tm->sec - utc_time_t);
1662
+
1663
+ return mrb_fixnum_value(offset_seconds);
1664
+ }
1665
+
1666
+ /* ---------------------------*/
1667
+ static const mrb_mt_entry time_rom_entries[] = {
1668
+ MRB_MT_ENTRY(time_hash, MRB_SYM(hash), MRB_ARGS_NONE()),
1669
+ MRB_MT_ENTRY(time_eq, MRB_SYM_Q(eql), MRB_ARGS_REQ(1)),
1670
+ MRB_MT_ENTRY(time_eq, MRB_OPSYM(eq), MRB_ARGS_REQ(1)),
1671
+ MRB_MT_ENTRY(time_cmp, MRB_OPSYM(cmp), MRB_ARGS_REQ(1)), /* 15.2.19.7.1 */
1672
+ MRB_MT_ENTRY(time_plus, MRB_OPSYM(add), MRB_ARGS_REQ(1)), /* 15.2.19.7.2 */
1673
+ MRB_MT_ENTRY(time_minus, MRB_OPSYM(sub), MRB_ARGS_REQ(1)), /* 15.2.19.7.3 */
1674
+ MRB_MT_ENTRY(time_to_s, MRB_SYM(to_s), MRB_ARGS_NONE()),
1675
+ MRB_MT_ENTRY(time_to_s, MRB_SYM(inspect), MRB_ARGS_NONE()),
1676
+ MRB_MT_ENTRY(time_asctime, MRB_SYM(asctime), MRB_ARGS_NONE()), /* 15.2.19.7.4 */
1677
+ MRB_MT_ENTRY(time_asctime, MRB_SYM(ctime), MRB_ARGS_NONE()), /* 15.2.19.7.5 */
1678
+ MRB_MT_ENTRY(time_day, MRB_SYM(day), MRB_ARGS_NONE()), /* 15.2.19.7.6 */
1679
+ MRB_MT_ENTRY(time_dst_p, MRB_SYM_Q(dst), MRB_ARGS_NONE()), /* 15.2.19.7.7 */
1680
+ MRB_MT_ENTRY(time_getutc, MRB_SYM(getgm), MRB_ARGS_NONE()), /* 15.2.19.7.8 */
1681
+ MRB_MT_ENTRY(time_getlocal, MRB_SYM(getlocal), MRB_ARGS_NONE()), /* 15.2.19.7.9 */
1682
+ MRB_MT_ENTRY(time_getutc, MRB_SYM(getutc), MRB_ARGS_NONE()), /* 15.2.19.7.10 */
1683
+ MRB_MT_ENTRY(time_utc_p, MRB_SYM_Q(gmt), MRB_ARGS_NONE()), /* 15.2.19.7.11 */
1684
+ MRB_MT_ENTRY(time_utc, MRB_SYM(gmtime), MRB_ARGS_NONE()), /* 15.2.19.7.13 */
1685
+ MRB_MT_ENTRY(time_hour, MRB_SYM(hour), MRB_ARGS_NONE()), /* 15.2.19.7.15 */
1686
+ MRB_MT_ENTRY(time_localtime, MRB_SYM(localtime), MRB_ARGS_NONE()), /* 15.2.19.7.18 */
1687
+ MRB_MT_ENTRY(time_day, MRB_SYM(mday), MRB_ARGS_NONE()), /* 15.2.19.7.19 */
1688
+ MRB_MT_ENTRY(time_min, MRB_SYM(min), MRB_ARGS_NONE()), /* 15.2.19.7.20 */
1689
+ MRB_MT_ENTRY(time_mon, MRB_SYM(mon), MRB_ARGS_NONE()), /* 15.2.19.7.21 */
1690
+ MRB_MT_ENTRY(time_mon, MRB_SYM(month), MRB_ARGS_NONE()), /* 15.2.19.7.22 */
1691
+ MRB_MT_ENTRY(time_sec, MRB_SYM(sec), MRB_ARGS_NONE()), /* 15.2.19.7.23 */
1692
+ MRB_MT_ENTRY(time_to_i, MRB_SYM(to_i), MRB_ARGS_NONE()), /* 15.2.19.7.25 */
1693
+ MRB_MT_ENTRY(time_usec, MRB_SYM(usec), MRB_ARGS_NONE()), /* 15.2.19.7.26 */
1694
+ MRB_MT_ENTRY(time_nsec, MRB_SYM(nsec), MRB_ARGS_NONE()),
1695
+ MRB_MT_ENTRY(time_nsec, MRB_SYM(tv_nsec), MRB_ARGS_NONE()),
1696
+ MRB_MT_ENTRY(time_utc, MRB_SYM(utc), MRB_ARGS_NONE()), /* 15.2.19.7.27 */
1697
+ MRB_MT_ENTRY(time_utc_p, MRB_SYM_Q(utc), MRB_ARGS_NONE()), /* 15.2.19.7.28 */
1698
+ MRB_MT_ENTRY(time_wday, MRB_SYM(wday), MRB_ARGS_NONE()), /* 15.2.19.7.30 */
1699
+ MRB_MT_ENTRY(time_yday, MRB_SYM(yday), MRB_ARGS_NONE()), /* 15.2.19.7.31 */
1700
+ MRB_MT_ENTRY(time_year, MRB_SYM(year), MRB_ARGS_NONE()), /* 15.2.19.7.32 */
1701
+ MRB_MT_ENTRY(time_zone, MRB_SYM(zone), MRB_ARGS_NONE()), /* 15.2.19.7.33 */
1702
+ MRB_MT_ENTRY(time_init, MRB_SYM(initialize), MRB_ARGS_OPT(7) | MRB_MT_PRIVATE), /* 15.2.19.7.16 */
1703
+ MRB_MT_ENTRY(time_init_copy, MRB_SYM(initialize_copy), MRB_ARGS_REQ(1) | MRB_MT_PRIVATE), /* 15.2.19.7.17 */
1704
+ MRB_MT_ENTRY(time_sunday, MRB_SYM_Q(sunday), MRB_ARGS_NONE()),
1705
+ MRB_MT_ENTRY(time_monday, MRB_SYM_Q(monday), MRB_ARGS_NONE()),
1706
+ MRB_MT_ENTRY(time_tuesday, MRB_SYM_Q(tuesday), MRB_ARGS_NONE()),
1707
+ MRB_MT_ENTRY(time_wednesday, MRB_SYM_Q(wednesday), MRB_ARGS_NONE()),
1708
+ MRB_MT_ENTRY(time_thursday, MRB_SYM_Q(thursday), MRB_ARGS_NONE()),
1709
+ MRB_MT_ENTRY(time_friday, MRB_SYM_Q(friday), MRB_ARGS_NONE()),
1710
+ MRB_MT_ENTRY(time_saturday, MRB_SYM_Q(saturday), MRB_ARGS_NONE()),
1711
+ MRB_MT_ENTRY(time_utc_offset, MRB_SYM(gmt_offset), MRB_ARGS_NONE()), /* 15.2.19.7.12 */
1712
+ MRB_MT_ENTRY(time_utc_offset, MRB_SYM(gmtoff), MRB_ARGS_NONE()), /* 15.2.19.7.14 */
1713
+ MRB_MT_ENTRY(time_utc_offset, MRB_SYM(utc_offset), MRB_ARGS_NONE()), /* 15.2.19.7.29 */
1714
+ #ifndef MRB_NO_FLOAT
1715
+ MRB_MT_ENTRY(time_to_f, MRB_SYM(to_f), MRB_ARGS_NONE()), /* 15.2.19.7.24 */
1716
+ #endif
1717
+ };
1718
+
1719
+ void
1720
+ mrb_mruby_time_gem_init(mrb_state* mrb)
1721
+ {
1722
+ /* ISO 15.2.19.2 */
1723
+ struct RClass *tc = mrb_define_class_id(mrb, MRB_SYM(Time), mrb->object_class);
1724
+ MRB_SET_INSTANCE_TT(tc, MRB_TT_CDATA);
1725
+ mrb_include_module(mrb, tc, mrb_module_get_id(mrb, MRB_SYM(Comparable)));
1726
+ mrb_define_class_method_id(mrb, tc, MRB_SYM(at), time_at_m, MRB_ARGS_ARG(1, 1)); /* 15.2.19.6.1 */
1727
+ mrb_define_class_method_id(mrb, tc, MRB_SYM(gm), time_gm, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.2 */
1728
+ mrb_define_class_method_id(mrb, tc, MRB_SYM(local), time_local, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.3 */
1729
+ mrb_define_class_method_id(mrb, tc, MRB_SYM(mktime), time_local, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.4 */
1730
+ mrb_define_class_method_id(mrb, tc, MRB_SYM(now), time_now, MRB_ARGS_NONE()); /* 15.2.19.6.5 */
1731
+ mrb_define_class_method_id(mrb, tc, MRB_SYM(utc), time_gm, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.6 */
1732
+
1733
+ MRB_MT_INIT_ROM(mrb, tc, time_rom_entries);
1734
+ }
1735
+
1736
+ void
1737
+ mrb_mruby_time_gem_final(mrb_state* mrb)
1738
+ {
1739
+ }